Only duplicate string the first time around, i.e. 'pinfo->fd->flags.visited == FALSE...
[obnox/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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #include <time.h>
36 #include <string.h>
37 #include <glib.h>
38 #include <ctype.h>
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include <epan/emem.h>
42 #include <epan/dissectors/packet-smb.h>
43 #include <epan/strutil.h>
44 #include <epan/prefs.h>
45 #include <epan/reassemble.h>
46 #include <epan/tap.h>
47 #include "packet-ipx.h"
48 #include "packet-idp.h"
49
50 #include "packet-windows-common.h"
51 #include "packet-smb-common.h"
52 #include "packet-smb-mailslot.h"
53 #include "packet-smb-pipe.h"
54 #include "packet-dcerpc.h"
55 #include "packet-ntlmssp.h"
56 #include "packet-smb2.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS specification from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/tech_activities/CIFS
67  *
68  * (it supercedes the document at
69  *
70  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
71  *
72  * ).
73  *
74  * There are also some Open Group publications documenting CIFS available
75  * for download; catalog entries for them are at:
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c209.htm
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c195.htm
80  *
81  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
82  * can be found at
83  *
84  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
85  *
86  * (or, presumably a similar path under the Samba mirrors).  As the
87  * ".doc" indicates, it's a Word document.  Some of the specs from the
88  * Microsoft FTP site can be found in the
89  *
90  *      http://www.samba.org/samba/ftp/specs/
91  *
92  * directory as well.
93  *
94  * Beware - these specs may have errors.
95  */
96
97 /* DFS referral entry flags */
98 #define REFENT_FLAGS_NAME_LIST_REFERRAL  0x0002
99 #define REFENT_FLAGS_TARGET_SET_BOUNDARY 0x0004
100
101
102 static int proto_smb = -1;
103 static int hf_smb_cmd = -1;
104 static int hf_smb_mapped_in = -1;
105 static int hf_smb_unmapped_in = -1;
106 static int hf_smb_opened_in = -1;
107 static int hf_smb_closed_in = -1;
108 static int hf_smb_key = -1;
109 static int hf_smb_session_id = -1;
110 static int hf_smb_sequence_num = -1;
111 static int hf_smb_group_id = -1;
112 static int hf_smb_pid = -1;
113 static int hf_smb_tid = -1;
114 static int hf_smb_uid = -1;
115 static int hf_smb_mid = -1;
116 static int hf_smb_pid_high = -1;
117 static int hf_smb_sig = -1;
118 static int hf_smb_response_to = -1;
119 static int hf_smb_time = -1;
120 static int hf_smb_response_in = -1;
121 static int hf_smb_continuation_to = -1;
122 static int hf_smb_nt_status = -1;
123 static int hf_smb_error_class = -1;
124 static int hf_smb_error_code = -1;
125 static int hf_smb_reserved = -1;
126 static int hf_smb_create_flags = -1;
127 static int hf_smb_create_options = -1;
128 static int hf_smb_share_access = -1;
129 static int hf_smb_access_mask = -1;
130 static int hf_smb_flags_lock = -1;
131 static int hf_smb_flags_receive_buffer = -1;
132 static int hf_smb_flags_caseless = -1;
133 static int hf_smb_flags_canon = -1;
134 static int hf_smb_flags_oplock = -1;
135 static int hf_smb_flags_notify = -1;
136 static int hf_smb_flags_response = -1;
137 static int hf_smb_flags2_long_names_allowed = -1;
138 static int hf_smb_flags2_ea = -1;
139 static int hf_smb_flags2_sec_sig = -1;
140 static int hf_smb_flags2_long_names_used = -1;
141 static int hf_smb_flags2_esn = -1;
142 static int hf_smb_flags2_dfs = -1;
143 static int hf_smb_flags2_roe = -1;
144 static int hf_smb_flags2_nt_error = -1;
145 static int hf_smb_flags2_string = -1;
146 static int hf_smb_word_count = -1;
147 static int hf_smb_byte_count = -1;
148 static int hf_smb_buffer_format = -1;
149 static int hf_smb_dialect_name = -1;
150 static int hf_smb_dialect_index = -1;
151 static int hf_smb_max_trans_buf_size = -1;
152 static int hf_smb_max_mpx_count = -1;
153 static int hf_smb_max_vcs_num = -1;
154 static int hf_smb_session_key = -1;
155 static int hf_smb_server_timezone = -1;
156 static int hf_smb_encryption_key_length = -1;
157 static int hf_smb_encryption_key = -1;
158 static int hf_smb_primary_domain = -1;
159 static int hf_smb_server = -1;
160 static int hf_smb_max_raw_buf_size = -1;
161 static int hf_smb_server_guid = -1;
162 static int hf_smb_security_blob_len = -1;
163 static int hf_smb_security_blob = -1;
164 static int hf_smb_sm_mode16 = -1;
165 static int hf_smb_sm_password16 = -1;
166 static int hf_smb_sm_mode = -1;
167 static int hf_smb_sm_password = -1;
168 static int hf_smb_sm_signatures = -1;
169 static int hf_smb_sm_sig_required = -1;
170 static int hf_smb_rm_read = -1;
171 static int hf_smb_rm_write = -1;
172 static int hf_smb_server_date_time = -1;
173 static int hf_smb_server_smb_date = -1;
174 static int hf_smb_server_smb_time = -1;
175 static int hf_smb_server_cap_raw_mode = -1;
176 static int hf_smb_server_cap_mpx_mode = -1;
177 static int hf_smb_server_cap_unicode = -1;
178 static int hf_smb_server_cap_large_files = -1;
179 static int hf_smb_server_cap_nt_smbs = -1;
180 static int hf_smb_server_cap_rpc_remote_apis = -1;
181 static int hf_smb_server_cap_nt_status = -1;
182 static int hf_smb_server_cap_level_ii_oplocks = -1;
183 static int hf_smb_server_cap_lock_and_read = -1;
184 static int hf_smb_server_cap_nt_find = -1;
185 static int hf_smb_server_cap_dfs = -1;
186 static int hf_smb_server_cap_infolevel_passthru = -1;
187 static int hf_smb_server_cap_large_readx = -1;
188 static int hf_smb_server_cap_large_writex = -1;
189 static int hf_smb_server_cap_unix = -1;
190 static int hf_smb_server_cap_reserved = -1;
191 static int hf_smb_server_cap_bulk_transfer = -1;
192 static int hf_smb_server_cap_compressed_data = -1;
193 static int hf_smb_server_cap_extended_security = -1;
194 static int hf_smb_system_time = -1;
195 static int hf_smb_unknown = -1;
196 static int hf_smb_dir_name = -1;
197 static int hf_smb_echo_count = -1;
198 static int hf_smb_echo_data = -1;
199 static int hf_smb_echo_seq_num = -1;
200 static int hf_smb_max_buf_size = -1;
201 static int hf_smb_password = -1;
202 static int hf_smb_password_len = -1;
203 static int hf_smb_ansi_password = -1;
204 static int hf_smb_ansi_password_len = -1;
205 static int hf_smb_unicode_password = -1;
206 static int hf_smb_unicode_password_len = -1;
207 static int hf_smb_path = -1;
208 static int hf_smb_service = -1;
209 static int hf_smb_move_flags_file = -1;
210 static int hf_smb_move_flags_dir = -1;
211 static int hf_smb_move_flags_verify = -1;
212 static int hf_smb_files_moved = -1;
213 static int hf_smb_file_access_mask_read_data = -1;
214 static int hf_smb_file_access_mask_write_data = -1;
215 static int hf_smb_file_access_mask_append_data = -1;
216 static int hf_smb_file_access_mask_read_ea = -1;
217 static int hf_smb_file_access_mask_write_ea = -1;
218 static int hf_smb_file_access_mask_execute = -1;
219 static int hf_smb_file_access_mask_read_attribute = -1;
220 static int hf_smb_file_access_mask_write_attribute = -1;
221 static int hf_smb_dir_access_mask_list = -1;
222 static int hf_smb_dir_access_mask_add_file = -1;
223 static int hf_smb_dir_access_mask_add_subdir = -1;
224 static int hf_smb_dir_access_mask_read_ea = -1;
225 static int hf_smb_dir_access_mask_write_ea = -1;
226 static int hf_smb_dir_access_mask_traverse = -1;
227 static int hf_smb_dir_access_mask_delete_child = -1;
228 static int hf_smb_dir_access_mask_read_attribute = -1;
229 static int hf_smb_dir_access_mask_write_attribute = -1;
230 static int hf_smb_copy_flags_file = -1;
231 static int hf_smb_copy_flags_dir = -1;
232 static int hf_smb_copy_flags_dest_mode = -1;
233 static int hf_smb_copy_flags_source_mode = -1;
234 static int hf_smb_copy_flags_verify = -1;
235 static int hf_smb_copy_flags_tree_copy = -1;
236 static int hf_smb_copy_flags_ea_action = -1;
237 static int hf_smb_count = -1;
238 static int hf_smb_count_low = -1;
239 static int hf_smb_count_high = -1;
240 static int hf_smb_file_name = -1;
241 static int hf_smb_open_function_open = -1;
242 static int hf_smb_open_function_create = -1;
243 static int hf_smb_fid = -1;
244 static int hf_smb_file_attr_read_only_16bit = -1;
245 static int hf_smb_file_attr_read_only_8bit = -1;
246 static int hf_smb_file_attr_hidden_16bit = -1;
247 static int hf_smb_file_attr_hidden_8bit = -1;
248 static int hf_smb_file_attr_system_16bit = -1;
249 static int hf_smb_file_attr_system_8bit = -1;
250 static int hf_smb_file_attr_volume_16bit = -1;
251 static int hf_smb_file_attr_volume_8bit = -1;
252 static int hf_smb_file_attr_directory_16bit = -1;
253 static int hf_smb_file_attr_directory_8bit = -1;
254 static int hf_smb_file_attr_archive_16bit = -1;
255 static int hf_smb_file_attr_archive_8bit = -1;
256 static int hf_smb_file_attr_device = -1;
257 static int hf_smb_file_attr_normal = -1;
258 static int hf_smb_file_attr_temporary = -1;
259 static int hf_smb_file_attr_sparse = -1;
260 static int hf_smb_file_attr_reparse = -1;
261 static int hf_smb_file_attr_compressed = -1;
262 static int hf_smb_file_attr_offline = -1;
263 static int hf_smb_file_attr_not_content_indexed = -1;
264 static int hf_smb_file_attr_encrypted = -1;
265 static int hf_smb_file_size = -1;
266 static int hf_smb_search_attribute_read_only = -1;
267 static int hf_smb_search_attribute_hidden = -1;
268 static int hf_smb_search_attribute_system = -1;
269 static int hf_smb_search_attribute_volume = -1;
270 static int hf_smb_search_attribute_directory = -1;
271 static int hf_smb_search_attribute_archive = -1;
272 static int hf_smb_access_mode = -1;
273 static int hf_smb_access_sharing = -1;
274 static int hf_smb_access_locality = -1;
275 static int hf_smb_access_caching = -1;
276 static int hf_smb_access_writetru = -1;
277 static int hf_smb_create_time = -1;
278 static int hf_smb_modify_time = -1;
279 static int hf_smb_backup_time = -1;
280 static int hf_smb_mac_alloc_block_count = -1;
281 static int hf_smb_mac_alloc_block_size = -1;
282 static int hf_smb_mac_free_block_count = -1;
283 static int hf_smb_mac_fndrinfo = -1;
284 static int hf_smb_mac_root_file_count = -1;
285 static int hf_smb_mac_root_dir_count = -1;
286 static int hf_smb_mac_file_count = -1;
287 static int hf_smb_mac_dir_count = -1;
288 static int hf_smb_mac_support_flags = -1;
289 static int hf_smb_mac_sup_access_ctrl = -1;
290 static int hf_smb_mac_sup_getset_comments = -1;
291 static int hf_smb_mac_sup_desktopdb_calls = -1;
292 static int hf_smb_mac_sup_unique_ids = -1;
293 static int hf_smb_mac_sup_streams = -1;
294 static int hf_smb_create_dos_date = -1;
295 static int hf_smb_create_dos_time = -1;
296 static int hf_smb_last_write_time = -1;
297 static int hf_smb_last_write_dos_date = -1;
298 static int hf_smb_last_write_dos_time = -1;
299 static int hf_smb_access_time = -1;
300 static int hf_smb_access_dos_date = -1;
301 static int hf_smb_access_dos_time = -1;
302 static int hf_smb_old_file_name = -1;
303 static int hf_smb_offset = -1;
304 static int hf_smb_remaining = -1;
305 static int hf_smb_padding = -1;
306 static int hf_smb_file_data = -1;
307 static int hf_smb_total_data_len = -1;
308 static int hf_smb_data_len = -1;
309 static int hf_smb_data_len_low = -1;
310 static int hf_smb_data_len_high = -1;
311 static int hf_smb_seek_mode = -1;
312 static int hf_smb_data_size = -1;
313 static int hf_smb_alloc_size = -1;
314 static int hf_smb_alloc_size64 = -1;
315 static int hf_smb_max_count = -1;
316 static int hf_smb_max_count_low = -1;
317 static int hf_smb_max_count_high = -1;
318 static int hf_smb_min_count = -1;
319 static int hf_smb_timeout = -1;
320 static int hf_smb_high_offset = -1;
321 static int hf_smb_units = -1;
322 static int hf_smb_bpu = -1;
323 static int hf_smb_blocksize = -1;
324 static int hf_smb_freeunits = -1;
325 static int hf_smb_data_offset = -1;
326 static int hf_smb_dcm = -1;
327 static int hf_smb_request_mask = -1;
328 static int hf_smb_response_mask = -1;
329 static int hf_smb_search_id = -1;
330 static int hf_smb_write_mode_write_through = -1;
331 static int hf_smb_write_mode_return_remaining = -1;
332 static int hf_smb_write_mode_raw = -1;
333 static int hf_smb_write_mode_message_start = -1;
334 static int hf_smb_write_mode_connectionless = -1;
335 static int hf_smb_resume_key_len = -1;
336 static int hf_smb_resume_find_id = -1;
337 static int hf_smb_resume_server_cookie = -1;
338 static int hf_smb_resume_client_cookie = -1;
339 static int hf_smb_andxoffset = -1;
340 static int hf_smb_lock_type_large = -1;
341 static int hf_smb_lock_type_cancel = -1;
342 static int hf_smb_lock_type_change = -1;
343 static int hf_smb_lock_type_oplock = -1;
344 static int hf_smb_lock_type_shared = -1;
345 static int hf_smb_locking_ol = -1;
346 static int hf_smb_number_of_locks = -1;
347 static int hf_smb_number_of_unlocks = -1;
348 static int hf_smb_lock_long_offset = -1;
349 static int hf_smb_lock_long_length = -1;
350 static int hf_smb_file_type = -1;
351 static int hf_smb_ipc_state_nonblocking = -1;
352 static int hf_smb_ipc_state_endpoint = -1;
353 static int hf_smb_ipc_state_pipe_type = -1;
354 static int hf_smb_ipc_state_read_mode = -1;
355 static int hf_smb_ipc_state_icount = -1;
356 static int hf_smb_server_fid = -1;
357 static int hf_smb_open_flags_add_info = -1;
358 static int hf_smb_open_flags_ex_oplock = -1;
359 static int hf_smb_open_flags_batch_oplock = -1;
360 static int hf_smb_open_flags_ealen = -1;
361 static int hf_smb_open_action_open = -1;
362 static int hf_smb_open_action_lock = -1;
363 static int hf_smb_vc_num = -1;
364 static int hf_smb_account = -1;
365 static int hf_smb_os = -1;
366 static int hf_smb_lanman = -1;
367 static int hf_smb_setup_action_guest = -1;
368 static int hf_smb_fs = -1;
369 static int hf_smb_connect_flags_dtid = -1;
370 static int hf_smb_connect_support_search = -1;
371 static int hf_smb_connect_support_in_dfs = -1;
372 static int hf_smb_max_setup_count = -1;
373 static int hf_smb_total_param_count = -1;
374 static int hf_smb_total_data_count = -1;
375 static int hf_smb_max_param_count = -1;
376 static int hf_smb_max_data_count = -1;
377 static int hf_smb_param_disp16 = -1;
378 static int hf_smb_param_count16 = -1;
379 static int hf_smb_param_offset16 = -1;
380 static int hf_smb_param_disp32 = -1;
381 static int hf_smb_param_count32 = -1;
382 static int hf_smb_param_offset32 = -1;
383 static int hf_smb_data_disp16 = -1;
384 static int hf_smb_data_count16 = -1;
385 static int hf_smb_data_offset16 = -1;
386 static int hf_smb_data_disp32 = -1;
387 static int hf_smb_data_count32 = -1;
388 static int hf_smb_data_offset32 = -1;
389 static int hf_smb_setup_count = -1;
390 static int hf_smb_nt_trans_subcmd = -1;
391 static int hf_smb_nt_ioctl_isfsctl = -1;
392 static int hf_smb_nt_ioctl_flags_root_handle = -1;
393 #ifdef SMB_UNUSED_HANDLES
394 static int hf_smb_nt_security_information = -1;
395 #endif
396 static int hf_smb_nt_notify_action = -1;
397 static int hf_smb_nt_notify_watch_tree = -1;
398 static int hf_smb_nt_notify_stream_write = -1;
399 static int hf_smb_nt_notify_stream_size = -1;
400 static int hf_smb_nt_notify_stream_name = -1;
401 static int hf_smb_nt_notify_security = -1;
402 static int hf_smb_nt_notify_ea = -1;
403 static int hf_smb_nt_notify_creation = -1;
404 static int hf_smb_nt_notify_last_access = -1;
405 static int hf_smb_nt_notify_last_write = -1;
406 static int hf_smb_nt_notify_size = -1;
407 static int hf_smb_nt_notify_attributes = -1;
408 static int hf_smb_nt_notify_dir_name = -1;
409 static int hf_smb_nt_notify_file_name = -1;
410 static int hf_smb_root_dir_fid = -1;
411 static int hf_smb_nt_create_disposition = -1;
412 static int hf_smb_sd_length = -1;
413 static int hf_smb_ea_list_length = -1;
414 static int hf_smb_ea_flags = -1;
415 static int hf_smb_ea_name_length = -1;
416 static int hf_smb_ea_data_length = -1;
417 static int hf_smb_ea_name = -1;
418 static int hf_smb_ea_data = -1;
419 static int hf_smb_file_name_len = -1;
420 static int hf_smb_nt_impersonation_level = -1;
421 static int hf_smb_nt_security_flags_context_tracking = -1;
422 static int hf_smb_nt_security_flags_effective_only = -1;
423 static int hf_smb_nt_access_mask_generic_read = -1;
424 static int hf_smb_nt_access_mask_generic_write = -1;
425 static int hf_smb_nt_access_mask_generic_execute = -1;
426 static int hf_smb_nt_access_mask_generic_all = -1;
427 static int hf_smb_nt_access_mask_maximum_allowed = -1;
428 static int hf_smb_nt_access_mask_system_security = -1;
429 static int hf_smb_nt_access_mask_synchronize = -1;
430 static int hf_smb_nt_access_mask_write_owner = -1;
431 static int hf_smb_nt_access_mask_write_dac = -1;
432 static int hf_smb_nt_access_mask_read_control = -1;
433 static int hf_smb_nt_access_mask_delete = -1;
434 static int hf_smb_nt_access_mask_write_attributes = -1;
435 static int hf_smb_nt_access_mask_read_attributes = -1;
436 static int hf_smb_nt_access_mask_delete_child = -1;
437 static int hf_smb_nt_access_mask_execute = -1;
438 static int hf_smb_nt_access_mask_write_ea = -1;
439 static int hf_smb_nt_access_mask_read_ea = -1;
440 static int hf_smb_nt_access_mask_append = -1;
441 static int hf_smb_nt_access_mask_write = -1;
442 static int hf_smb_nt_access_mask_read = -1;
443 static int hf_smb_nt_create_bits_oplock = -1;
444 static int hf_smb_nt_create_bits_boplock = -1;
445 static int hf_smb_nt_create_bits_dir = -1;
446 static int hf_smb_nt_create_bits_ext_resp = -1;
447 static int hf_smb_nt_create_options_directory_file = -1;
448 static int hf_smb_nt_create_options_write_through = -1;
449 static int hf_smb_nt_create_options_sequential_only = -1;
450 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
451 static int hf_smb_nt_create_options_sync_io_alert = -1;
452 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
453 static int hf_smb_nt_create_options_non_directory_file = -1;
454 static int hf_smb_nt_create_options_create_tree_connection = -1;
455 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
456 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
457 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
458 static int hf_smb_nt_create_options_random_access = -1;
459 static int hf_smb_nt_create_options_delete_on_close = -1;
460 static int hf_smb_nt_create_options_open_by_fileid = -1;
461 static int hf_smb_nt_create_options_backup_intent = -1;
462 static int hf_smb_nt_create_options_no_compression = -1;
463 static int hf_smb_nt_create_options_reserve_opfilter = -1;
464 static int hf_smb_nt_create_options_open_reparse_point = -1;
465 static int hf_smb_nt_create_options_open_no_recall = -1;
466 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
467 static int hf_smb_nt_share_access_read = -1;
468 static int hf_smb_nt_share_access_write = -1;
469 static int hf_smb_nt_share_access_delete = -1;
470 static int hf_smb_file_eattr_read_only = -1;
471 static int hf_smb_file_eattr_hidden = -1;
472 static int hf_smb_file_eattr_system = -1;
473 static int hf_smb_file_eattr_volume = -1;
474 static int hf_smb_file_eattr_directory = -1;
475 static int hf_smb_file_eattr_archive = -1;
476 static int hf_smb_file_eattr_device = -1;
477 static int hf_smb_file_eattr_normal = -1;
478 static int hf_smb_file_eattr_temporary = -1;
479 static int hf_smb_file_eattr_sparse = -1;
480 static int hf_smb_file_eattr_reparse = -1;
481 static int hf_smb_file_eattr_compressed = -1;
482 static int hf_smb_file_eattr_offline = -1;
483 static int hf_smb_file_eattr_not_content_indexed = -1;
484 static int hf_smb_file_eattr_encrypted = -1;
485 static int hf_smb_sec_desc_len = -1;
486 static int hf_smb_nt_qsd_owner = -1;
487 static int hf_smb_nt_qsd_group = -1;
488 static int hf_smb_nt_qsd_dacl = -1;
489 static int hf_smb_nt_qsd_sacl = -1;
490 static int hf_smb_extended_attributes = -1;
491 static int hf_smb_oplock_level = -1;
492 static int hf_smb_create_action = -1;
493 static int hf_smb_file_id = -1;
494 static int hf_smb_ea_error_offset = -1;
495 static int hf_smb_end_of_file = -1;
496 static int hf_smb_replace = -1;
497 static int hf_smb_root_dir_handle = -1;
498 static int hf_smb_target_name_len = -1;
499 static int hf_smb_target_name = -1;
500 static int hf_smb_device_type = -1;
501 static int hf_smb_is_directory = -1;
502 static int hf_smb_next_entry_offset = -1;
503 static int hf_smb_change_time = -1;
504 static int hf_smb_setup_len = -1;
505 static int hf_smb_print_mode = -1;
506 static int hf_smb_print_identifier = -1;
507 static int hf_smb_restart_index = -1;
508 static int hf_smb_print_queue_date = -1;
509 static int hf_smb_print_queue_dos_date = -1;
510 static int hf_smb_print_queue_dos_time = -1;
511 static int hf_smb_print_status = -1;
512 static int hf_smb_print_spool_file_number = -1;
513 static int hf_smb_print_spool_file_size = -1;
514 static int hf_smb_print_spool_file_name = -1;
515 static int hf_smb_start_index = -1;
516 static int hf_smb_originator_name = -1;
517 static int hf_smb_destination_name = -1;
518 static int hf_smb_message_len = -1;
519 static int hf_smb_message = -1;
520 static int hf_smb_mgid = -1;
521 static int hf_smb_forwarded_name = -1;
522 static int hf_smb_machine_name = -1;
523 static int hf_smb_cancel_to = -1;
524 static int hf_smb_trans2_subcmd = -1;
525 static int hf_smb_trans_name = -1;
526 static int hf_smb_transaction_flags_dtid = -1;
527 static int hf_smb_transaction_flags_owt = -1;
528 static int hf_smb_search_count = -1;
529 static int hf_smb_search_pattern = -1;
530 static int hf_smb_ff2_backup = -1;
531 static int hf_smb_ff2_continue = -1;
532 static int hf_smb_ff2_resume = -1;
533 static int hf_smb_ff2_close_eos = -1;
534 static int hf_smb_ff2_close = -1;
535 static int hf_smb_ff2_information_level = -1;
536 static int hf_smb_qpi_loi = -1;
537 static int hf_smb_spi_loi = -1;
538 #if 0
539 static int hf_smb_sfi_writetru = -1;
540 static int hf_smb_sfi_caching = -1;
541 #endif
542 static int hf_smb_storage_type = -1;
543 static int hf_smb_resume = -1;
544 static int hf_smb_max_referral_level = -1;
545 static int hf_smb_qfsi_information_level = -1;
546 static int hf_smb_number_of_links = -1;
547 static int hf_smb_delete_pending = -1;
548 static int hf_smb_index_number = -1;
549 static int hf_smb_position = -1;
550 static int hf_smb_current_offset = -1;
551 static int hf_smb_t2_alignment = -1;
552 static int hf_smb_t2_stream_name_length = -1;
553 static int hf_smb_t2_stream_size = -1;
554 static int hf_smb_t2_stream_name = -1;
555 static int hf_smb_t2_compressed_file_size = -1;
556 static int hf_smb_t2_compressed_format = -1;
557 static int hf_smb_t2_compressed_unit_shift = -1;
558 static int hf_smb_t2_compressed_chunk_shift = -1;
559 static int hf_smb_t2_compressed_cluster_shift = -1;
560 static int hf_smb_t2_marked_for_deletion = -1;
561 static int hf_smb_dfs_path_consumed = -1;
562 static int hf_smb_dfs_num_referrals = -1;
563 static int hf_smb_get_dfs_server_hold_storage = -1;
564 static int hf_smb_get_dfs_fielding = -1;
565 static int hf_smb_dfs_referral_version = -1;
566 static int hf_smb_dfs_referral_size = -1;
567 static int hf_smb_dfs_referral_server_type = -1;
568 static int hf_smb_dfs_referral_flags_name_list_referral = -1;
569 static int hf_smb_dfs_referral_flags_target_set_boundary = -1;
570 static int hf_smb_dfs_referral_node_offset = -1;
571 static int hf_smb_dfs_referral_node = -1;
572 static int hf_smb_dfs_referral_proximity = -1;
573 static int hf_smb_dfs_referral_ttl = -1;
574 static int hf_smb_dfs_referral_path_offset = -1;
575 static int hf_smb_dfs_referral_path = -1;
576 static int hf_smb_dfs_referral_alt_path_offset = -1;
577 static int hf_smb_dfs_referral_alt_path = -1;
578 static int hf_smb_dfs_referral_domain_offset = -1;
579 static int hf_smb_dfs_referral_number_of_expnames = -1;
580 static int hf_smb_dfs_referral_expnames_offset = -1;
581 static int hf_smb_dfs_referral_domain_name = -1;
582 static int hf_smb_dfs_referral_expname = -1;
583 static int hf_smb_dfs_referral_server_guid = -1;
584 static int hf_smb_end_of_search = -1;
585 static int hf_smb_last_name_offset = -1;
586 static int hf_smb_fn_information_level = -1;
587 static int hf_smb_monitor_handle = -1;
588 static int hf_smb_change_count = -1;
589 static int hf_smb_file_index = -1;
590 static int hf_smb_short_file_name = -1;
591 static int hf_smb_short_file_name_len = -1;
592 static int hf_smb_fs_id = -1;
593 static int hf_smb_sector_unit = -1;
594 static int hf_smb_fs_units = -1;
595 static int hf_smb_fs_sector = -1;
596 static int hf_smb_avail_units = -1;
597 static int hf_smb_volume_serial_num = -1;
598 static int hf_smb_volume_label_len = -1;
599 static int hf_smb_volume_label = -1;
600 static int hf_smb_free_alloc_units64 = -1;
601 static int hf_smb_caller_free_alloc_units64 = -1;
602 static int hf_smb_actual_free_alloc_units64 = -1;
603 static int hf_smb_max_name_len = -1;
604 static int hf_smb_fs_name_len = -1;
605 static int hf_smb_fs_name = -1;
606 static int hf_smb_device_char_removable = -1;
607 static int hf_smb_device_char_read_only = -1;
608 static int hf_smb_device_char_floppy = -1;
609 static int hf_smb_device_char_write_once = -1;
610 static int hf_smb_device_char_remote = -1;
611 static int hf_smb_device_char_mounted = -1;
612 static int hf_smb_device_char_virtual = -1;
613 static int hf_smb_fs_attr_css = -1;
614 static int hf_smb_fs_attr_cpn = -1;
615 static int hf_smb_fs_attr_uod = -1;
616 static int hf_smb_fs_attr_pacls = -1;
617 static int hf_smb_fs_attr_fc = -1;
618 static int hf_smb_fs_attr_vq = -1;
619 static int hf_smb_fs_attr_ssf = -1;
620 static int hf_smb_fs_attr_srp = -1;
621 static int hf_smb_fs_attr_srs = -1;
622 static int hf_smb_fs_attr_sla = -1;
623 static int hf_smb_fs_attr_vic = -1;
624 static int hf_smb_fs_attr_soids = -1;
625 static int hf_smb_fs_attr_se = -1;
626 static int hf_smb_fs_attr_ns = -1;
627 static int hf_smb_fs_attr_rov = -1;
628 static int hf_smb_quota_flags_enabled = -1;
629 static int hf_smb_quota_flags_deny_disk = -1;
630 static int hf_smb_quota_flags_log_limit = -1;
631 static int hf_smb_quota_flags_log_warning = -1;
632 static int hf_smb_soft_quota_limit = -1;
633 static int hf_smb_hard_quota_limit = -1;
634 static int hf_smb_user_quota_used = -1;
635 static int hf_smb_user_quota_offset = -1;
636 static int hf_smb_nt_rename_level = -1;
637 static int hf_smb_cluster_count = -1;
638 static int hf_smb_segments = -1;
639 static int hf_smb_segment = -1;
640 static int hf_smb_segment_overlap = -1;
641 static int hf_smb_segment_overlap_conflict = -1;
642 static int hf_smb_segment_multiple_tails = -1;
643 static int hf_smb_segment_too_long_fragment = -1;
644 static int hf_smb_segment_error = -1;
645 static int hf_smb_pipe_write_len = -1;
646 static int hf_smb_unix_major_version = -1;
647 static int hf_smb_unix_minor_version = -1;
648 static int hf_smb_unix_capability_fcntl = -1;
649 static int hf_smb_unix_capability_posix_acl = -1;
650 static int hf_smb_unix_file_size = -1;
651 static int hf_smb_unix_file_num_bytes = -1;
652 static int hf_smb_unix_file_last_status = -1;
653 static int hf_smb_unix_file_last_access = -1;
654 static int hf_smb_unix_file_last_change = -1;
655 static int hf_smb_unix_file_uid = -1;
656 static int hf_smb_unix_file_gid = -1;
657 static int hf_smb_unix_file_type = -1;
658 static int hf_smb_unix_file_dev_major = -1;
659 static int hf_smb_unix_file_dev_minor = -1;
660 static int hf_smb_unix_file_unique_id = -1;
661 static int hf_smb_unix_file_permissions = -1;
662 static int hf_smb_unix_file_nlinks = -1;
663 static int hf_smb_unix_file_link_dest = -1;
664 static int hf_smb_unix_find_file_nextoffset = -1;
665 static int hf_smb_unix_find_file_resumekey = -1;
666 static int hf_smb_network_unknown = -1;
667 static int hf_smb_disposition_delete_on_close = -1;
668 static int hf_smb_pipe_info_flag = -1;
669 static int hf_smb_mode = -1;
670 static int hf_smb_attribute = -1;
671 static int hf_smb_reparse_tag = -1;
672 static int hf_smb_logged_in = -1;
673 static int hf_smb_logged_out = -1;
674 static int hf_smb_file_rw_offset = -1;
675 static int hf_smb_file_rw_length = -1;
676 static int hf_smb_posix_acl_version = -1;
677 static int hf_smb_posix_num_file_aces = -1;
678 static int hf_smb_posix_num_def_aces = -1;
679 static int hf_smb_posix_ace_type = -1;
680 static int hf_smb_posix_ace_flags = -1;
681 static int hf_smb_posix_ace_perm_read = -1;
682 static int hf_smb_posix_ace_perm_write = -1;
683 static int hf_smb_posix_ace_perm_execute = -1;
684 static int hf_smb_posix_ace_perm_owner_uid = -1;
685 static int hf_smb_posix_ace_perm_owner_gid = -1;
686 static int hf_smb_posix_ace_perm_uid = -1;
687 static int hf_smb_posix_ace_perm_gid = -1;
688
689 static gint ett_smb = -1;
690 static gint ett_smb_fid = -1;
691 static gint ett_smb_tid = -1;
692 static gint ett_smb_uid = -1;
693 static gint ett_smb_hdr = -1;
694 static gint ett_smb_command = -1;
695 static gint ett_smb_fileattributes = -1;
696 static gint ett_smb_capabilities = -1;
697 static gint ett_smb_aflags = -1;
698 static gint ett_smb_dialect = -1;
699 static gint ett_smb_dialects = -1;
700 static gint ett_smb_mode = -1;
701 static gint ett_smb_rawmode = -1;
702 static gint ett_smb_flags = -1;
703 static gint ett_smb_flags2 = -1;
704 static gint ett_smb_desiredaccess = -1;
705 static gint ett_smb_search = -1;
706 static gint ett_smb_file = -1;
707 static gint ett_smb_openfunction = -1;
708 static gint ett_smb_filetype = -1;
709 static gint ett_smb_openaction = -1;
710 static gint ett_smb_writemode = -1;
711 static gint ett_smb_lock_type = -1;
712 static gint ett_smb_ssetupandxaction = -1;
713 static gint ett_smb_optionsup = -1;
714 static gint ett_smb_time_date = -1;
715 static gint ett_smb_move_copy_flags = -1;
716 static gint ett_smb_file_attributes = -1;
717 static gint ett_smb_search_resume_key = -1;
718 static gint ett_smb_search_dir_info = -1;
719 static gint ett_smb_unlocks = -1;
720 static gint ett_smb_unlock = -1;
721 static gint ett_smb_locks = -1;
722 static gint ett_smb_lock = -1;
723 static gint ett_smb_open_flags = -1;
724 static gint ett_smb_ipc_state = -1;
725 static gint ett_smb_open_action = -1;
726 static gint ett_smb_setup_action = -1;
727 static gint ett_smb_connect_flags = -1;
728 static gint ett_smb_connect_support_bits = -1;
729 static gint ett_smb_nt_access_mask = -1;
730 static gint ett_smb_nt_create_bits = -1;
731 static gint ett_smb_nt_create_options = -1;
732 static gint ett_smb_nt_share_access = -1;
733 static gint ett_smb_nt_security_flags = -1;
734 static gint ett_smb_nt_trans_setup = -1;
735 static gint ett_smb_nt_trans_data = -1;
736 static gint ett_smb_nt_trans_param = -1;
737 static gint ett_smb_nt_notify_completion_filter = -1;
738 static gint ett_smb_nt_ioctl_flags = -1;
739 static gint ett_smb_security_information_mask = -1;
740 static gint ett_smb_print_queue_entry = -1;
741 static gint ett_smb_transaction_flags = -1;
742 static gint ett_smb_transaction_params = -1;
743 static gint ett_smb_find_first2_flags = -1;
744 static gint ett_smb_mac_support_flags = -1;
745 #if 0
746 static gint ett_smb_ioflag = -1;
747 #endif
748 static gint ett_smb_transaction_data = -1;
749 static gint ett_smb_stream_info = -1;
750 static gint ett_smb_dfs_referrals = -1;
751 static gint ett_smb_dfs_referral = -1;
752 static gint ett_smb_dfs_referral_flags = -1;
753 static gint ett_smb_dfs_referral_expnames = -1;
754 static gint ett_smb_get_dfs_flags = -1;
755 static gint ett_smb_ff2_data = -1;
756 static gint ett_smb_device_characteristics = -1;
757 static gint ett_smb_fs_attributes = -1;
758 static gint ett_smb_segments = -1;
759 static gint ett_smb_segment = -1;
760 static gint ett_smb_quotaflags = -1;
761 static gint ett_smb_secblob = -1;
762 static gint ett_smb_unicode_password = -1;
763 static gint ett_smb_ea = -1;
764 static gint ett_smb_unix_capabilities = -1;
765 static gint ett_smb_posic_ace = -1;
766 static gint ett_smb_posix_ace_perms = -1;
767
768 static int smb_tap = -1;
769
770 static dissector_handle_t gssapi_handle;
771 static dissector_handle_t ntlmssp_handle;
772
773 static const fragment_items smb_frag_items = {
774         &ett_smb_segment,
775         &ett_smb_segments,
776
777         &hf_smb_segments,
778         &hf_smb_segment,
779         &hf_smb_segment_overlap,
780         &hf_smb_segment_overlap_conflict,
781         &hf_smb_segment_multiple_tails,
782         &hf_smb_segment_too_long_fragment,
783         &hf_smb_segment_error,
784         NULL,
785
786         "segments"
787 };
788
789 static proto_tree *top_tree=NULL;     /* ugly */
790
791 static const char *decode_smb_name(guint8);
792 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
793
794 /*
795  * Macros for use in the main dissector routines for an SMB.
796  */
797
798 #define WORD_COUNT      \
799         /* Word Count */                                \
800         wc = tvb_get_guint8(tvb, offset);               \
801         proto_tree_add_uint(tree, hf_smb_word_count,    \
802                 tvb, offset, 1, wc);                    \
803         offset += 1;                                    \
804         if(wc==0) goto bytecount;
805
806 #define BYTE_COUNT      \
807         bytecount:                                      \
808         bc = tvb_get_letohs(tvb, offset);               \
809         proto_tree_add_uint(tree, hf_smb_byte_count,    \
810                         tvb, offset, 2, bc);            \
811         offset += 2;                                    \
812         if(bc==0) goto endofcommand;
813
814 #define CHECK_BYTE_COUNT(len)   \
815         if (bc < len) goto endofcommand;
816
817 #define COUNT_BYTES(len)   {\
818         int tmp;            \
819         tmp=len;            \
820         offset += tmp;      \
821         bc -= tmp;          \
822         }
823
824 #define END_OF_SMB      \
825         if (bc != 0) { \
826                 gint bc_remaining; \
827                 bc_remaining=tvb_length_remaining(tvb, offset); \
828                 if( ((gint)bc) > bc_remaining){ \
829                         bc=bc_remaining; \
830                 } \
831                 if(bc){ \
832                         tvb_ensure_bytes_exist(tvb, offset, bc); \
833                         proto_tree_add_text(tree, tvb, offset, bc, \
834                             "Extra byte parameters");           \
835                 } \
836                 offset += bc;                           \
837         }                                               \
838         endofcommand:
839
840 /*
841  * Macros for use in routines called by them.
842  */
843 #define CHECK_BYTE_COUNT_SUBR(len)      \
844         if (*bcp < len) {               \
845                 *trunc = TRUE;          \
846                 return offset;          \
847         }
848
849 #define CHECK_STRING_SUBR(fn)   \
850         if (fn == NULL) {       \
851                 *trunc = TRUE;  \
852                 return offset;  \
853         }
854
855 #define COUNT_BYTES_SUBR(len)   \
856         offset += len;          \
857         *bcp -= len;
858
859 /*
860  * Macros for use when dissecting transaction parameters and data
861  */
862 #define CHECK_BYTE_COUNT_TRANS(len)     \
863         if (bc < len) return offset;
864
865 #define CHECK_STRING_TRANS(fn)  \
866         if (fn == NULL) return offset;
867
868 #define COUNT_BYTES_TRANS(len)  \
869         offset += len;          \
870         bc -= len;
871
872 /*
873  * Macros for use in subrroutines dissecting transaction parameters or data
874  */
875 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
876         if (*bcp < len) return offset;
877
878 #define CHECK_STRING_TRANS_SUBR(fn)     \
879         if (fn == NULL) return offset;
880
881 #define COUNT_BYTES_TRANS_SUBR(len)     \
882         offset += len;                  \
883         *bcp -= len;
884
885
886 gboolean sid_name_snooping = FALSE;
887
888 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
889    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
890    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
891 static gboolean smb_trans_reassembly = TRUE;
892 gboolean smb_dcerpc_reassembly = TRUE;
893
894 static GHashTable *smb_trans_fragment_table = NULL;
895
896 static void
897 smb_trans_reassembly_init(void)
898 {
899         fragment_table_init(&smb_trans_fragment_table);
900 }
901
902 /*
903  * XXX - This keeps us from allocating huge amounts of memory as shown in
904  * bug 421.  It may need to be increased.
905  */
906 #define MAX_FRAGMENT_SIZE 65536
907 static fragment_data *
908 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
909                      int offset, int count, int pos, int totlen)
910 {
911         fragment_data *fd_head=NULL;
912         smb_info_t *si;
913         int more_frags;
914
915         if (count > MAX_FRAGMENT_SIZE || count < 0) {
916                 THROW(ReportedBoundsError);
917         }
918
919         more_frags=totlen>(pos+count);
920
921         si = (smb_info_t *)pinfo->private_data;
922         DISSECTOR_ASSERT(si);
923
924         if (si->sip == NULL) {
925                 /*
926                  * We don't have the frame number of the request.
927                  */
928                 return NULL;
929         }
930
931         if(!pinfo->fd->flags.visited){
932                 fd_head = fragment_add(tvb, offset, pinfo,
933                                        si->sip->frame_req, smb_trans_fragment_table,
934                                        pos, count, more_frags);
935         } else {
936                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
937         }
938
939         if (!fd_head || !(fd_head->flags&FD_DEFRAGMENTED)){
940                 /* This is continued - mark it as such, so we recognize
941                    continuation responses.
942                 */
943                 si->sip->flags |= SMB_SIF_IS_CONTINUED;
944         } else {
945                 /* We've finished reassembling, so there are no more
946                    continuation responses.
947                 */
948                 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
949         }
950
951         /* we only show the defragmented packet for the first fragment,
952            or else we might end up with dissecting one HUGE transaction PDU
953            a LOT of times. (first fragment is the only one containing the setup
954            bytes)
955            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
956            SMBs. Takes a LOT of time dissecting and is not fun.
957         */
958         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
959                 return fd_head;
960         } else {
961                 return NULL;
962         }
963 }
964
965
966
967
968
969 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
970    These variables and functions are used to match
971    responses with calls
972    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
973 /*
974  * The information we need to save about a request in order to show the
975  * frame number of the request in the dissection of the reply.
976  */
977 typedef struct  {
978         guint32 frame;
979         guint32 pid_mid;
980 } smb_saved_info_key_t;
981
982 /* unmatched smb_saved_info structures.
983    For unmatched smb_saved_info structures we store the smb_saved_info
984    structure using the MID and the PID as the key.
985
986    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
987    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
988    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
989 */
990 static gint
991 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
992 {
993         register guint32 key1 = GPOINTER_TO_UINT(k1);
994         register guint32 key2 = GPOINTER_TO_UINT(k2);
995         return key1==key2;
996 }
997 static guint
998 smb_saved_info_hash_unmatched(gconstpointer k)
999 {
1000         register guint32 key = GPOINTER_TO_UINT(k);
1001         return key;
1002 }
1003
1004 /* matched smb_saved_info structures.
1005    For matched smb_saved_info structures we store the smb_saved_info
1006    structure twice in the table using the frame number, and a combination
1007    of the MID and the PID, as the key.
1008    The frame number is guaranteed to be unique but if ever someone makes
1009    some change that will renumber the frames in a capture we are in BIG trouble.
1010    This is not likely though since that would break (among other things) all the
1011    reassembly routines as well.
1012
1013    We also need the MID as there may be more than one SMB request or reply
1014    in a single frame, and we also need the PID as there may be more than
1015    one outstanding request with the same MID and different PIDs.
1016 */
1017 static gint
1018 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1019 {
1020         const smb_saved_info_key_t *key1 = k1;
1021         const smb_saved_info_key_t *key2 = k2;
1022         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
1023 }
1024 static guint
1025 smb_saved_info_hash_matched(gconstpointer k)
1026 {
1027         const smb_saved_info_key_t *key = k;
1028         return key->frame + key->pid_mid;
1029 }
1030
1031 static GSList *conv_tables = NULL;
1032
1033
1034 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1035    End of request/response matching functions
1036    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1037
1038
1039
1040 typedef struct _smb_uid_t {
1041         char *domain;
1042         char *account;
1043         int logged_in;
1044         int logged_out;
1045 } smb_uid_t;
1046
1047 static void
1048 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1049 {
1050         mask&=0x0000ffff;
1051         if(mask==0x000001ff){
1052                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1053         }
1054
1055
1056         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1057         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1058         proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1059         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1060         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1061         proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1062         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1063         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1064 }
1065 struct access_mask_info smb_file_access_mask_info = {
1066         "FILE",                         /* Name of specific rights */
1067         smb_file_specific_rights,       /* Dissection function */
1068         NULL,                           /* Generic mapping table */
1069         NULL                            /* Standard mapping table */
1070 };
1071
1072
1073 static void
1074 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1075 {
1076         mask&=0x0000ffff;
1077         if(mask==0x000001ff){
1078                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1079         }
1080
1081
1082         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1083         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1084         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1085         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1086         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1087         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1088         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1089         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1090         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1091 }
1092 struct access_mask_info smb_dir_access_mask_info = {
1093         "DIR",                          /* Name of specific rights */
1094         smb_dir_specific_rights,        /* Dissection function */
1095         NULL,                           /* Generic mapping table */
1096         NULL                            /* Standard mapping table */
1097 };
1098
1099
1100
1101 static const value_string buffer_format_vals[] = {
1102         {1,     "Data Block"},
1103         {2,     "Dialect"},
1104         {3,     "Pathname"},
1105         {4,     "ASCII"},
1106         {5,     "Variable Block"},
1107         {0,     NULL}
1108 };
1109
1110 #define POSIX_ACE_TYPE_USER_OBJ         0x01
1111 #define POSIX_ACE_TYPE_USER             0x02
1112 #define POSIX_ACE_TYPE_GROUP_OBJ        0x04
1113 #define POSIX_ACE_TYPE_GROUP            0x08
1114 #define POSIX_ACE_TYPE_MASK             0x10
1115 #define POSIX_ACE_TYPE_OTHER            0x20
1116 static const value_string ace_type_vals[] = {
1117         {POSIX_ACE_TYPE_USER_OBJ,       "User Obj"},
1118         {POSIX_ACE_TYPE_USER,           "User"},
1119         {POSIX_ACE_TYPE_GROUP_OBJ,      "Group Obj"},
1120         {POSIX_ACE_TYPE_GROUP,          "Group"},
1121         {POSIX_ACE_TYPE_MASK,           "Mask"},
1122         {POSIX_ACE_TYPE_OTHER,          "Other"},
1123         {0,     NULL}
1124 };
1125
1126 /*
1127  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1128  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1129  * January 1, 1970, 00:00:00 GMT.
1130  *
1131  * This means we have to do some extra work to convert it.  This code is
1132  * based on the Samba code:
1133  *
1134  *      Unix SMB/Netbios implementation.
1135  *      Version 1.9.
1136  *      time handling functions
1137  *      Copyright (C) Andrew Tridgell 1992-1998
1138  */
1139
1140 /*
1141  * Yield the difference between *A and *B, in seconds, ignoring leap
1142  * seconds.
1143  */
1144 #define TM_YEAR_BASE 1900
1145
1146 static int
1147 tm_diff(struct tm *a, struct tm *b)
1148 {
1149         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1150         int by = b->tm_year + (TM_YEAR_BASE - 1);
1151         int intervening_leap_days =
1152             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1153         int years = ay - by;
1154         int days =
1155             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1156         int hours = 24*days + (a->tm_hour - b->tm_hour);
1157         int minutes = 60*hours + (a->tm_min - b->tm_min);
1158         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1159
1160         return seconds;
1161 }
1162
1163 /*
1164  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1165  * determined.
1166  */
1167 static int
1168 TimeZone(time_t t)
1169 {
1170         struct tm *tm = gmtime(&t);
1171         struct tm tm_utc;
1172
1173         if (tm == NULL)
1174                 return 0;
1175         tm_utc = *tm;
1176         tm = localtime(&t);
1177         if (tm == NULL)
1178                 return 0;
1179         return tm_diff(&tm_utc,tm);
1180 }
1181
1182 /*
1183  * Return the same value as TimeZone, but it should be more efficient.
1184  *
1185  * We keep a table of DST offsets to prevent calling localtime() on each
1186  * call of this function. This saves a LOT of time on many unixes.
1187  *
1188  * Updated by Paul Eggert <eggert@twinsun.com>
1189  */
1190 #ifndef CHAR_BIT
1191 #define CHAR_BIT 8
1192 #endif
1193
1194 #ifndef TIME_T_MIN
1195 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1196                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1197 #endif
1198 #ifndef TIME_T_MAX
1199 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1200 #endif
1201
1202 static int
1203 TimeZoneFaster(time_t t)
1204 {
1205         static struct dst_table {time_t start,end; int zone;} *tdt;
1206         static struct dst_table *dst_table = NULL;
1207         static int table_size = 0;
1208         int i;
1209         int zone = 0;
1210
1211         if (t == 0)
1212                 t = time(NULL);
1213
1214         /* Tunis has a 8 day DST region, we need to be careful ... */
1215 #define MAX_DST_WIDTH (365*24*60*60)
1216 #define MAX_DST_SKIP (7*24*60*60)
1217
1218         for (i = 0; i < table_size; i++) {
1219                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1220                         break;
1221         }
1222
1223         if (i < table_size) {
1224                 zone = dst_table[i].zone;
1225         } else {
1226                 time_t low,high;
1227
1228                 zone = TimeZone(t);
1229                 if (dst_table == NULL)
1230                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1231                 else
1232                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1233                 if (tdt == NULL) {
1234                         g_free(dst_table);
1235                         table_size = 0;
1236                 } else {
1237                         dst_table = tdt;
1238                         table_size++;
1239
1240                         dst_table[i].zone = zone;
1241                         dst_table[i].start = dst_table[i].end = t;
1242
1243                         /* no entry will cover more than 6 months */
1244                         low = t - MAX_DST_WIDTH/2;
1245                         /* XXX - what if t < MAX_DST_WIDTH/2? */
1246
1247                         high = t + MAX_DST_WIDTH/2;
1248                         /* XXX - what if this overflows? */
1249
1250                         /*
1251                          * Widen the new entry using two bisection searches.
1252                          */
1253                         while (low+60*60 < dst_table[i].start) {
1254                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1255                                         t = dst_table[i].start - MAX_DST_SKIP;
1256                                 else
1257                                         t = low + (dst_table[i].start-low)/2;
1258                                 if (TimeZone(t) == zone)
1259                                         dst_table[i].start = t;
1260                                 else
1261                                         low = t;
1262                         }
1263
1264                         while (high-60*60 > dst_table[i].end) {
1265                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1266                                         t = dst_table[i].end + MAX_DST_SKIP;
1267                                 else
1268                                         t = high - (high-dst_table[i].end)/2;
1269                                 if (TimeZone(t) == zone)
1270                                         dst_table[i].end = t;
1271                                 else
1272                                         high = t;
1273                         }
1274                 }
1275         }
1276         return zone;
1277 }
1278
1279 /*
1280  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1281  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1282  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1283  * daylight savings transitions because some local times are ambiguous.
1284  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1285  */
1286 static int
1287 LocTimeDiff(time_t lt)
1288 {
1289         int d = TimeZoneFaster(lt);
1290         time_t t = lt + d;
1291
1292         /* if overflow occurred, ignore all the adjustments so far */
1293         if (((t < lt) ^ (d < 0)))
1294                 t = lt;
1295
1296         /*
1297          * Now t should be close enough to the true UTC to yield the
1298          * right answer.
1299          */
1300         return TimeZoneFaster(t);
1301 }
1302
1303 static int
1304 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1305 {
1306         guint32 timeval;
1307         nstime_t ts;
1308
1309         timeval = tvb_get_letohl(tvb, offset);
1310         if (timeval == 0xffffffff) {
1311                 proto_tree_add_text(tree, tvb, offset, 4,
1312                     "%s: No time specified (0xffffffff)",
1313                     proto_registrar_get_name(hf_date));
1314                 offset += 4;
1315                 return offset;
1316         }
1317
1318         /*
1319          * We add the local time offset.
1320          */
1321         ts.secs = timeval + LocTimeDiff(timeval);
1322         ts.nsecs = 0;
1323
1324         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1325         offset += 4;
1326
1327         return offset;
1328 }
1329
1330 static int
1331 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1332     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1333 {
1334         guint16 dos_time, dos_date;
1335         proto_item *item = NULL;
1336         proto_tree *tree = NULL;
1337         struct tm tm;
1338         time_t t;
1339         static const int mday_noleap[12] = {
1340                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1341         };
1342         static const int mday_leap[12] = {
1343                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1344         };
1345 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1346         nstime_t tv;
1347
1348         if (time_first) {
1349                 dos_time = tvb_get_letohs(tvb, offset);
1350                 dos_date = tvb_get_letohs(tvb, offset+2);
1351         } else {
1352                 dos_date = tvb_get_letohs(tvb, offset);
1353                 dos_time = tvb_get_letohs(tvb, offset+2);
1354         }
1355
1356         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1357             (dos_date == 0 && dos_time == 0)) {
1358                 /*
1359                  * No date/time specified.
1360                  */
1361                 if(parent_tree){
1362                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1363                             "%s: No time specified (0x%08x)",
1364                             proto_registrar_get_name(hf_date),
1365                             (dos_date << 16) | dos_time);
1366                 }
1367                 offset += 4;
1368                 return offset;
1369         }
1370
1371         tm.tm_sec = (dos_time&0x1f)*2;
1372         tm.tm_min = (dos_time>>5)&0x3f;
1373         tm.tm_hour = (dos_time>>11)&0x1f;
1374         tm.tm_mday = dos_date&0x1f;
1375         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1376         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1377         tm.tm_isdst = -1;
1378
1379         /*
1380          * Do some sanity checks before calling "mktime()";
1381          * "mktime()" doesn't do them, it "normalizes" out-of-range
1382          * values.
1383          */
1384         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1385            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1386            (ISLEAP(tm.tm_year + 1900) ?
1387              tm.tm_mday > mday_leap[tm.tm_mon] :
1388              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1389              (t = mktime(&tm)) == -1) {
1390                 /*
1391                  * Invalid date/time.
1392                  */
1393                 if (parent_tree) {
1394                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1395                             "%s: Invalid time",
1396                             proto_registrar_get_name(hf_date));
1397                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1398                         if (time_first) {
1399                                 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);
1400                                 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);
1401                         } else {
1402                                 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);
1403                                 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);
1404                         }
1405                 }
1406                 offset += 4;
1407                 return offset;
1408         }
1409
1410         tv.secs = t;
1411         tv.nsecs = 0;
1412
1413         if(parent_tree){
1414                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1415                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1416                 if (time_first) {
1417                         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);
1418                         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);
1419                 } else {
1420                         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);
1421                         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);
1422                 }
1423         }
1424
1425         offset += 4;
1426
1427         return offset;
1428 }
1429
1430 static const true_false_string tfs_disposition_delete_on_close = {
1431         "DELETE this file when closed",
1432         "Normal access, do not delete on close"
1433 };
1434
1435 static const true_false_string tfs_pipe_info_flag = {
1436         "SET NAMED PIPE mode",
1437         "Clear NAMED PIPE mode"
1438 };
1439
1440
1441 static const value_string da_access_vals[] = {
1442         { 0,            "Open for reading"},
1443         { 1,            "Open for writing"},
1444         { 2,            "Open for reading and writing"},
1445         { 3,            "Open for execute"},
1446         {0, NULL}
1447 };
1448 static const value_string da_sharing_vals[] = {
1449         { 0,            "Compatibility mode"},
1450         { 1,            "Deny read/write/execute (exclusive)"},
1451         { 2,            "Deny write"},
1452         { 3,            "Deny read/execute"},
1453         { 4,            "Deny none"},
1454         {0, NULL}
1455 };
1456 static const value_string da_locality_vals[] = {
1457         { 0,            "Locality of reference unknown"},
1458         { 1,            "Mainly sequential access"},
1459         { 2,            "Mainly random access"},
1460         { 3,            "Random access with some locality"},
1461         {0, NULL}
1462 };
1463 static const true_false_string tfs_da_caching = {
1464         "Do not cache this file",
1465         "Caching permitted on this file"
1466 };
1467 static const true_false_string tfs_da_writetru = {
1468         "Write through enabled",
1469         "Write through disabled"
1470 };
1471 static int
1472 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1473 {
1474         guint16 mask;
1475         proto_item *item;
1476         proto_tree *tree;
1477
1478         mask = tvb_get_letohs(tvb, offset);
1479
1480         if(parent_tree){
1481                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1482                         "%s Access: 0x%04x", type, mask);
1483                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1484
1485                 proto_tree_add_boolean(tree, hf_smb_access_writetru,
1486                         tvb, offset, 2, mask);
1487                 proto_tree_add_boolean(tree, hf_smb_access_caching,
1488                         tvb, offset, 2, mask);
1489                 proto_tree_add_uint(tree, hf_smb_access_locality,
1490                         tvb, offset, 2, mask);
1491                 proto_tree_add_uint(tree, hf_smb_access_sharing,
1492                         tvb, offset, 2, mask);
1493                 proto_tree_add_uint(tree, hf_smb_access_mode,
1494                         tvb, offset, 2, mask);
1495         }
1496
1497         offset += 2;
1498
1499         return offset;
1500 }
1501
1502 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1503 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1504 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1505 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1506 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1507 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1508 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1509 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1510 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1511 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1512 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1513 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1514 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1515 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1516 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1517
1518 static const true_false_string tfs_file_attribute_read_only = {
1519         "This file is READ ONLY",
1520         "This file is NOT read only",
1521 };
1522 static const true_false_string tfs_file_attribute_hidden = {
1523         "This is a HIDDEN file",
1524         "This is NOT a hidden file"
1525 };
1526 static const true_false_string tfs_file_attribute_system = {
1527         "This is a SYSTEM file",
1528         "This is NOT a system file"
1529 };
1530 static const true_false_string tfs_file_attribute_volume = {
1531         "This is a VOLUME ID",
1532         "This is NOT a volume ID"
1533 };
1534 static const true_false_string tfs_file_attribute_directory = {
1535         "This is a DIRECTORY",
1536         "This is NOT a directory"
1537 };
1538 static const true_false_string tfs_file_attribute_archive = {
1539         "This file has been modified since last ARCHIVE",
1540         "This file has NOT been modified since last archive"
1541 };
1542 static const true_false_string tfs_file_attribute_device = {
1543         "This is a DEVICE",
1544         "This is NOT a device"
1545 };
1546 static const true_false_string tfs_file_attribute_normal = {
1547         "This file is an ordinary file",
1548         "This file has some attribute set"
1549 };
1550 static const true_false_string tfs_file_attribute_temporary = {
1551         "This is a TEMPORARY file",
1552         "This is NOT a temporary file"
1553 };
1554 static const true_false_string tfs_file_attribute_sparse = {
1555         "This is a SPARSE file",
1556         "This is NOT a sparse file"
1557 };
1558 static const true_false_string tfs_file_attribute_reparse = {
1559         "This file has an associated REPARSE POINT",
1560         "This file does NOT have an associated reparse point"
1561 };
1562 static const true_false_string tfs_file_attribute_compressed = {
1563         "This is a COMPRESSED file",
1564         "This is NOT a compressed file"
1565 };
1566 static const true_false_string tfs_file_attribute_offline = {
1567         "This file is OFFLINE",
1568         "This file is NOT offline"
1569 };
1570 static const true_false_string tfs_file_attribute_not_content_indexed = {
1571         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1572         "This file MAY be indexed by the content indexing service"
1573 };
1574 static const true_false_string tfs_file_attribute_encrypted = {
1575         "This is an ENCRYPTED file",
1576         "This is NOT an encrypted file"
1577 };
1578
1579 /*
1580  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are
1581  * listed as USHORT, and seem to be in packets in the wild, while in other
1582  * places they are listed as ULONG, and also seem to be.
1583  *
1584  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1585  * bytes to consume.
1586  */
1587
1588 int
1589 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1590                         int bytes)
1591 {
1592         guint16 mask;
1593         proto_item *item;
1594         proto_tree *tree;
1595
1596         if (bytes != 2 && bytes != 4) {
1597                 THROW(ReportedBoundsError);
1598         }
1599
1600         /*
1601          * The actual bits of interest appear to only be a USHORT
1602          */
1603         /* FIXME if this ever changes! */
1604         mask = tvb_get_letohs(tvb, offset);
1605
1606         if(parent_tree){
1607                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1608                         "File Attributes: 0x%08x", mask);
1609                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1610
1611                 proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1612                                        tvb, offset, bytes, mask);
1613                 proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1614                                        tvb, offset, bytes, mask);
1615                 proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1616                                        tvb, offset, bytes, mask);
1617                 proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1618                                        tvb, offset, bytes, mask);
1619                 proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1620                                        tvb, offset, bytes, mask);
1621                 proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1622                                        tvb, offset, bytes, mask);
1623                 proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1624                                        tvb, offset, bytes, mask);
1625                 proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1626                                        tvb, offset, bytes, mask);
1627                 proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1628                                        tvb, offset, bytes, mask);
1629                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1630                                 tvb, offset, bytes, mask);
1631                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1632                                 tvb, offset, bytes, mask);
1633                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1634                                 tvb, offset, bytes, mask);
1635                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1636                                 tvb, offset, bytes, mask);
1637                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1638                                 tvb, offset, bytes, mask);
1639                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1640                                 tvb, offset, bytes, mask);
1641         }
1642
1643         offset += bytes;
1644
1645         return offset;
1646 }
1647
1648 /* 3.11 */
1649 static int
1650 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1651     int len, guint32 mask)
1652 {
1653         proto_item *item;
1654         proto_tree *tree;
1655
1656         if(parent_tree){
1657                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
1658                         "File Attributes: 0x%08x", mask);
1659                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1660
1661                 /*
1662                  * XXX - Network Monitor disagrees on some of the
1663                  * bits, e.g. the bits above temporary are "atomic write"
1664                  * and "transaction write", and it says nothing about the
1665                  * bits above that.
1666                  *
1667                  * Does the Win32 API documentation, or the NT Native API book,
1668                  * suggest anything?
1669                  */
1670                 proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1671                         tvb, offset, len, mask);
1672                 proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1673                         tvb, offset, len, mask);
1674                 proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1675                         tvb, offset, len, mask);
1676                 proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1677                         tvb, offset, len, mask);
1678                 proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1679                         tvb, offset, len, mask);
1680                 proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1681                         tvb, offset, len, mask);
1682                 proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1683                         tvb, offset, len, mask);
1684                 proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1685                         tvb, offset, len, mask);
1686                 proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1687                         tvb, offset, len, mask);
1688                 proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1689                         tvb, offset, len, mask);
1690                 proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1691                         tvb, offset, len, mask);
1692                 proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1693                         tvb, offset, len, mask);
1694                 proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1695                         tvb, offset, len, mask);
1696                 proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1697                         tvb, offset, len, mask);
1698                 proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1699                         tvb, offset, len, mask);
1700         }
1701
1702         offset += len;
1703
1704         return offset;
1705 }
1706
1707 /* 3.11 */
1708 static int
1709 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1710 {
1711         guint32 mask;
1712
1713         mask = tvb_get_letohl(tvb, offset);
1714
1715         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1716
1717         return offset;
1718 }
1719
1720 static int
1721 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1722 {
1723         guint8 mask;
1724         proto_item *item;
1725         proto_tree *tree;
1726
1727         mask = tvb_get_guint8(tvb, offset);
1728
1729         if(parent_tree){
1730                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1731                         "File Attributes: 0x%02x", mask);
1732                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1733
1734                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1735                         tvb, offset, 1, mask);
1736                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1737                         tvb, offset, 1, mask);
1738                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1739                         tvb, offset, 1, mask);
1740                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1741                         tvb, offset, 1, mask);
1742                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1743                         tvb, offset, 1, mask);
1744                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1745                         tvb, offset, 1, mask);
1746         }
1747
1748         offset += 1;
1749
1750         return offset;
1751 }
1752
1753 static const true_false_string tfs_search_attribute_read_only = {
1754         "Include READ ONLY files in search results",
1755         "Do NOT include read only files in search results",
1756 };
1757 static const true_false_string tfs_search_attribute_hidden = {
1758         "Include HIDDEN files in search results",
1759         "Do NOT include hidden files in search results"
1760 };
1761 static const true_false_string tfs_search_attribute_system = {
1762         "Include SYSTEM files in search results",
1763         "Do NOT include system files in search results"
1764 };
1765 static const true_false_string tfs_search_attribute_volume = {
1766         "Include VOLUME IDs in search results",
1767         "Do NOT include volume IDs in search results"
1768 };
1769 static const true_false_string tfs_search_attribute_directory = {
1770         "Include DIRECTORIES in search results",
1771         "Do NOT include directories in search results"
1772 };
1773 static const true_false_string tfs_search_attribute_archive = {
1774         "Include ARCHIVE files in search results",
1775         "Do NOT include archive files in search results"
1776 };
1777
1778 static int
1779 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1780 {
1781         guint16 mask;
1782         proto_item *item;
1783         proto_tree *tree;
1784
1785         mask = tvb_get_letohs(tvb, offset);
1786
1787         if(parent_tree){
1788                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1789                         "Search Attributes: 0x%04x", mask);
1790                 tree = proto_item_add_subtree(item, ett_smb_search);
1791
1792                 proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1793                         tvb, offset, 2, mask);
1794                 proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1795                         tvb, offset, 2, mask);
1796                 proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1797                         tvb, offset, 2, mask);
1798                 proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1799                         tvb, offset, 2, mask);
1800                 proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1801                         tvb, offset, 2, mask);
1802                 proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1803                         tvb, offset, 2, mask);
1804         }
1805
1806         offset += 2;
1807         return offset;
1808 }
1809
1810 #if 0
1811 /*
1812  * XXX - this isn't used.
1813  * Is this used for anything?  NT Create AndX doesn't use it.
1814  * Is there some 16-bit attribute field with more bits than Read Only,
1815  * Hidden, System, Volume ID, Directory, and Archive?
1816  */
1817 static int
1818 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1819 {
1820         guint32 mask;
1821         proto_item *item;
1822         proto_tree *tree;
1823
1824         mask = tvb_get_letohl(tvb, offset);
1825
1826         if(parent_tree){
1827                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1828                         "File Attributes: 0x%08x", mask);
1829                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1830         }
1831         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1832                 tvb, offset, 2, mask);
1833         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1834                 tvb, offset, 2, mask);
1835         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1836                 tvb, offset, 2, mask);
1837         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1838                 tvb, offset, 2, mask);
1839         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1840                 tvb, offset, 2, mask);
1841         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1842                 tvb, offset, 2, mask);
1843         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1844                 tvb, offset, 2, mask);
1845         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1846                 tvb, offset, 2, mask);
1847         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1848                 tvb, offset, 2, mask);
1849         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1850                 tvb, offset, 2, mask);
1851         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1852                 tvb, offset, 2, mask);
1853         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1854                 tvb, offset, 2, mask);
1855         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1856                 tvb, offset, 2, mask);
1857         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1858                 tvb, offset, 2, mask);
1859         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1860                 tvb, offset, 2, mask);
1861
1862         offset += 2;
1863
1864         return offset;
1865 }
1866 #endif
1867
1868
1869 #define SERVER_CAP_RAW_MODE            0x00000001
1870 #define SERVER_CAP_MPX_MODE            0x00000002
1871 #define SERVER_CAP_UNICODE             0x00000004
1872 #define SERVER_CAP_LARGE_FILES         0x00000008
1873 #define SERVER_CAP_NT_SMBS             0x00000010
1874 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1875 #define SERVER_CAP_STATUS32            0x00000040
1876 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1877 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1878 #define SERVER_CAP_NT_FIND             0x00000200
1879 #define SERVER_CAP_DFS                 0x00001000
1880 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1881 #define SERVER_CAP_LARGE_READX         0x00004000
1882 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1883 #define SERVER_CAP_UNIX                0x00800000
1884 #define SERVER_CAP_RESERVED            0x02000000
1885 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1886 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1887 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1888 static const true_false_string tfs_server_cap_raw_mode = {
1889         "Read Raw and Write Raw are supported",
1890         "Read Raw and Write Raw are not supported"
1891 };
1892 static const true_false_string tfs_server_cap_mpx_mode = {
1893         "Read Mpx and Write Mpx are supported",
1894         "Read Mpx and Write Mpx are not supported"
1895 };
1896 static const true_false_string tfs_server_cap_unicode = {
1897         "Unicode strings are supported",
1898         "Unicode strings are not supported"
1899 };
1900 static const true_false_string tfs_server_cap_large_files = {
1901         "Large files are supported",
1902         "Large files are not supported",
1903 };
1904 static const true_false_string tfs_server_cap_nt_smbs = {
1905         "NT SMBs are supported",
1906         "NT SMBs are not supported"
1907 };
1908 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1909         "RPC remote APIs are supported",
1910         "RPC remote APIs are not supported"
1911 };
1912 static const true_false_string tfs_server_cap_nt_status = {
1913         "NT status codes are supported",
1914         "NT status codes are not supported"
1915 };
1916 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1917         "Level 2 oplocks are supported",
1918         "Level 2 oplocks are not supported"
1919 };
1920 static const true_false_string tfs_server_cap_lock_and_read = {
1921         "Lock and Read is supported",
1922         "Lock and Read is not supported"
1923 };
1924 static const true_false_string tfs_server_cap_nt_find = {
1925         "NT Find is supported",
1926         "NT Find is not supported"
1927 };
1928 static const true_false_string tfs_server_cap_dfs = {
1929         "Dfs is supported",
1930         "Dfs is not supported"
1931 };
1932 static const true_false_string tfs_server_cap_infolevel_passthru = {
1933         "NT information level request passthrough is supported",
1934         "NT information level request passthrough is not supported"
1935 };
1936 static const true_false_string tfs_server_cap_large_readx = {
1937         "Large Read andX is supported",
1938         "Large Read andX is not supported"
1939 };
1940 static const true_false_string tfs_server_cap_large_writex = {
1941         "Large Write andX is supported",
1942         "Large Write andX is not supported"
1943 };
1944 static const true_false_string tfs_server_cap_unix = {
1945         "UNIX extensions are supported",
1946         "UNIX extensions are not supported"
1947 };
1948 static const true_false_string tfs_server_cap_reserved = {
1949         "Reserved",
1950         "Reserved"
1951 };
1952 static const true_false_string tfs_server_cap_bulk_transfer = {
1953         "Bulk Read and Bulk Write are supported",
1954         "Bulk Read and Bulk Write are not supported"
1955 };
1956 static const true_false_string tfs_server_cap_compressed_data = {
1957         "Compressed data transfer is supported",
1958         "Compressed data transfer is not supported"
1959 };
1960 static const true_false_string tfs_server_cap_extended_security = {
1961         "Extended security exchanges are supported",
1962         "Extended security exchanges are not supported"
1963 };
1964 static int
1965 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1966 {
1967         guint32 mask;
1968         proto_item *item;
1969         proto_tree *tree;
1970
1971         mask = tvb_get_letohl(tvb, offset);
1972
1973         if(parent_tree){
1974                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1975                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1976
1977                 proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1978                         tvb, offset, 4, mask);
1979                 proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1980                         tvb, offset, 4, mask);
1981                 proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1982                         tvb, offset, 4, mask);
1983                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1984                         tvb, offset, 4, mask);
1985                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1986                         tvb, offset, 4, mask);
1987                 proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1988                         tvb, offset, 4, mask);
1989                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1990                         tvb, offset, 4, mask);
1991                 proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1992                         tvb, offset, 4, mask);
1993                 proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1994                         tvb, offset, 4, mask);
1995                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1996                         tvb, offset, 4, mask);
1997                 proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1998                         tvb, offset, 4, mask);
1999                 proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
2000                         tvb, offset, 4, mask);
2001                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
2002                         tvb, offset, 4, mask);
2003                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
2004                         tvb, offset, 4, mask);
2005                 proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
2006                         tvb, offset, 4, mask);
2007                 proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
2008                         tvb, offset, 4, mask);
2009                 proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
2010                         tvb, offset, 4, mask);
2011                 proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
2012                         tvb, offset, 4, mask);
2013                 proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
2014                         tvb, offset, 4, mask);
2015         }
2016
2017         return mask;
2018 }
2019
2020 #define RAWMODE_READ   0x01
2021 #define RAWMODE_WRITE  0x02
2022 static const true_false_string tfs_rm_read = {
2023         "Read Raw is supported",
2024         "Read Raw is not supported"
2025 };
2026 static const true_false_string tfs_rm_write = {
2027         "Write Raw is supported",
2028         "Write Raw is not supported"
2029 };
2030
2031 static int
2032 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2033 {
2034         guint16 mask;
2035         proto_item *item;
2036         proto_tree *tree;
2037
2038         mask = tvb_get_letohs(tvb, offset);
2039
2040         if(parent_tree){
2041                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
2042                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2043
2044                 proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2045                 proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2046         }
2047
2048         offset += 2;
2049
2050         return offset;
2051 }
2052
2053 #define SECURITY_MODE_MODE             0x01
2054 #define SECURITY_MODE_PASSWORD         0x02
2055 #define SECURITY_MODE_SIGNATURES       0x04
2056 #define SECURITY_MODE_SIG_REQUIRED     0x08
2057 static const true_false_string tfs_sm_mode = {
2058         "USER security mode",
2059         "SHARE security mode"
2060 };
2061 static const true_false_string tfs_sm_password = {
2062         "ENCRYPTED password. Use challenge/response",
2063         "PLAINTEXT password"
2064 };
2065 static const true_false_string tfs_sm_signatures = {
2066         "Security signatures ENABLED",
2067         "Security signatures NOT enabled"
2068 };
2069 static const true_false_string tfs_sm_sig_required = {
2070         "Security signatures REQUIRED",
2071         "Security signatures NOT required"
2072 };
2073
2074 static int
2075 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2076 {
2077         guint16 mask = 0;
2078         proto_item *item = NULL;
2079         proto_tree *tree = NULL;
2080
2081         switch(wc){
2082         case 13:
2083                 mask = tvb_get_letohs(tvb, offset);
2084                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2085                                 "Security Mode: 0x%04x", mask);
2086                 tree = proto_item_add_subtree(item, ett_smb_mode);
2087                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2088                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2089                 offset += 2;
2090                 break;
2091
2092         case 17:
2093                 mask = tvb_get_guint8(tvb, offset);
2094                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2095                                 "Security Mode: 0x%02x", mask);
2096                 tree = proto_item_add_subtree(item, ett_smb_mode);
2097                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2098                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2099                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2100                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2101                 offset += 1;
2102                 break;
2103         }
2104
2105         return offset;
2106 }
2107
2108 #define MAX_DIALECTS 20
2109 struct negprot_dialects {
2110        int num;
2111        char *name[MAX_DIALECTS+1];
2112 };
2113
2114 static int
2115 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2116 {
2117         proto_item *it = NULL;
2118         proto_tree *tr = NULL;
2119         guint16 bc;
2120         guint8 wc;
2121         struct negprot_dialects *dialects = NULL;
2122         smb_info_t *si;
2123
2124         si = (smb_info_t *)pinfo->private_data;
2125         DISSECTOR_ASSERT(si);
2126
2127         WORD_COUNT;
2128
2129         BYTE_COUNT;
2130
2131         if(tree){
2132                 tvb_ensure_bytes_exist(tvb, offset, bc);
2133                 it = proto_tree_add_text(tree, tvb, offset, bc,
2134                                 "Requested Dialects");
2135                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2136         }
2137
2138         if (!pinfo->fd->flags.visited && si->sip) {
2139                 dialects = se_alloc(sizeof(struct negprot_dialects));
2140                 dialects->num = 0;
2141                 si->sip->extra_info_type = SMB_EI_DIALECTS;
2142                 si->sip->extra_info = dialects;
2143         }
2144
2145         while(bc){
2146                 int len;
2147                 const guint8 *str;
2148                 proto_item *dit = NULL;
2149                 proto_tree *dtr = NULL;
2150
2151                 /* XXX - what if this runs past bc? */
2152                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2153                 len = tvb_strsize(tvb, offset+1);
2154                 str = tvb_get_ptr(tvb, offset+1, len);
2155
2156                 if(tr){
2157                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2158                                         "Dialect: %s", str);
2159                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2160                 }
2161
2162                 /* Buffer Format */
2163                 CHECK_BYTE_COUNT(1);
2164                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2165                         TRUE);
2166                 COUNT_BYTES(1);
2167
2168                 /*Dialect Name */
2169                 CHECK_BYTE_COUNT(len);
2170                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2171                         len, str);
2172                 COUNT_BYTES(len);
2173
2174                 if (!pinfo->fd->flags.visited && dialects && dialects->num<MAX_DIALECTS) {
2175                         dialects->name[dialects->num++] = se_strdup(str);
2176                 }
2177         }
2178
2179
2180         END_OF_SMB
2181
2182         return offset;
2183 }
2184
2185 static int
2186 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2187 {
2188         smb_info_t *si = pinfo->private_data;
2189         guint8 wc;
2190         guint16 dialect;
2191         const char *dn;
2192         int dn_len;
2193         guint16 bc;
2194         guint16 ekl=0;
2195         guint32 caps=0;
2196         gint16 tz;
2197         struct negprot_dialects *dialects = NULL;
2198         const char *dialect_name = NULL;
2199
2200         DISSECTOR_ASSERT(si);
2201
2202         WORD_COUNT;
2203
2204         /* Dialect Index */
2205         dialect = tvb_get_letohs(tvb, offset);
2206
2207         if (si->sip && si->sip->extra_info_type==SMB_EI_DIALECTS) {
2208                 dialects = si->sip->extra_info;
2209                 if (dialect <= dialects->num) {
2210                         dialect_name = dialects->name[dialect];
2211                 }
2212         }
2213         if (!dialect_name) {
2214                 dialect_name = "unknown";
2215         }
2216
2217         switch(wc){
2218         case 1:
2219                 if(dialect==0xffff){
2220                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2221                                 tvb, offset, 2, dialect,
2222                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2223                 } else {
2224                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2225                                 tvb, offset, 2, dialect);
2226                 }
2227                 break;
2228         case 13:
2229                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2230                         tvb, offset, 2, dialect,
2231                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2232                 break;
2233         case 17:
2234                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2235                         tvb, offset, 2, dialect,
2236                         "Dialect Index: %u: %s", dialect, dialect_name);
2237                 break;
2238         default:
2239                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2240                 proto_tree_add_text(tree, tvb, offset, wc*2,
2241                         "Words for unknown response format");
2242                 offset += wc*2;
2243                 goto bytecount;
2244         }
2245         offset += 2;
2246
2247         switch(wc){
2248         case 13:
2249                 /* Security Mode */
2250                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2251
2252                 /* Maximum Transmit Buffer Size */
2253                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2254                         tvb, offset, 2, TRUE);
2255                 offset += 2;
2256
2257                 /* Maximum Multiplex Count */
2258                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2259                         tvb, offset, 2, TRUE);
2260                 offset += 2;
2261
2262                 /* Maximum Vcs Number */
2263                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2264                         tvb, offset, 2, TRUE);
2265                 offset += 2;
2266
2267                 /* raw mode */
2268                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2269
2270                 /* session key */
2271                 proto_tree_add_item(tree, hf_smb_session_key,
2272                         tvb, offset, 4, TRUE);
2273                 offset += 4;
2274
2275                 /* current time and date at server */
2276                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2277                     TRUE);
2278
2279                 /* time zone */
2280                 tz = tvb_get_letohs(tvb, offset);
2281                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2282                 offset += 2;
2283
2284                 /* encryption key length */
2285                 ekl = tvb_get_letohs(tvb, offset);
2286                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2287                 offset += 2;
2288
2289                 /* 2 reserved bytes */
2290                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2291                 offset += 2;
2292
2293                 break;
2294
2295         case 17:
2296                 /* Security Mode */
2297                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2298
2299                 /* Maximum Multiplex Count */
2300                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2301                         tvb, offset, 2, TRUE);
2302                 offset += 2;
2303
2304                 /* Maximum Vcs Number */
2305                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2306                         tvb, offset, 2, TRUE);
2307                 offset += 2;
2308
2309                 /* Maximum Transmit Buffer Size */
2310                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2311                         tvb, offset, 4, TRUE);
2312                 offset += 4;
2313
2314                 /* maximum raw buffer size */
2315                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2316                         tvb, offset, 4, TRUE);
2317                 offset += 4;
2318
2319                 /* session key */
2320                 proto_tree_add_item(tree, hf_smb_session_key,
2321                         tvb, offset, 4, TRUE);
2322                 offset += 4;
2323
2324                 /* server capabilities */
2325                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2326                 offset += 4;
2327
2328                 /* system time */
2329                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2330                                 hf_smb_system_time);
2331
2332                 /* time zone */
2333                 tz = tvb_get_letohs(tvb, offset);
2334                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2335                         tvb, offset, 2, tz,
2336                         "Server Time Zone: %d min from UTC", tz);
2337                 offset += 2;
2338
2339                 /* encryption key length */
2340                 ekl = tvb_get_guint8(tvb, offset);
2341                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2342                         tvb, offset, 1, ekl);
2343                 offset += 1;
2344
2345                 break;
2346         }
2347
2348         BYTE_COUNT;
2349
2350         switch(wc){
2351         case 13:
2352                 /* challenge/response encryption key */
2353                 if(ekl){
2354                         CHECK_BYTE_COUNT(ekl);
2355                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2356                         COUNT_BYTES(ekl);
2357                 }
2358
2359                 /*
2360                  * Primary domain.
2361                  *
2362                  * XXX - not present if negotiated dialect isn't
2363                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2364                  * have to see the request, or assume what dialect strings
2365                  * were sent, to determine that.
2366                  *
2367                  * Is this something other than a primary domain if the
2368                  * negotiated dialect is Windows for Workgroups 3.1a?
2369                  * It appears to be 8 bytes of binary data in at least
2370                  * one capture - is that an encryption key or something
2371                  * such as that?
2372                  */
2373                 dn = get_unicode_or_ascii_string(tvb, &offset,
2374                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2375                 if (dn == NULL)
2376                         goto endofcommand;
2377                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2378                         offset, dn_len,dn);
2379                 COUNT_BYTES(dn_len);
2380                 break;
2381
2382         case 17:
2383                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2384                         /* challenge/response encryption key */
2385                         /* XXX - is this aligned on an even boundary? */
2386                         if(ekl){
2387                                 CHECK_BYTE_COUNT(ekl);
2388                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2389                                         tvb, offset, ekl, TRUE);
2390                                 COUNT_BYTES(ekl);
2391                         }
2392
2393                         /* domain */
2394                         /* this string is special, unicode is flagged in caps */
2395                         /* This string is NOT padded to be 16bit aligned.
2396                            (seen in actual capture)
2397                            XXX - I've seen a capture where it appears to be
2398                            so aligned, but I've also seen captures where
2399                            it is.  The captures where it appeared to be
2400                            aligned may have been from buggy servers. */
2401                         /* However, don't get rid of existing setting */
2402                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2403                           si->unicode;
2404
2405                         dn = get_unicode_or_ascii_string(tvb,
2406                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2407                                 &bc);
2408                         if (dn == NULL)
2409                                 goto endofcommand;
2410                         proto_tree_add_string(tree, hf_smb_primary_domain,
2411                                 tvb, offset, dn_len, dn);
2412                         COUNT_BYTES(dn_len);
2413
2414                         /* server name, seen in w2k pro capture */
2415                         dn = get_unicode_or_ascii_string(tvb,
2416                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2417                                 &bc);
2418                         if (dn == NULL)
2419                                 goto endofcommand;
2420                         proto_tree_add_string(tree, hf_smb_server,
2421                                 tvb, offset, dn_len, dn);
2422                         COUNT_BYTES(dn_len);
2423
2424                 } else {
2425                         proto_item *blob_item;
2426                         guint16 sbloblen;
2427
2428                         /* guid */
2429                         /* XXX - show it in the standard Microsoft format
2430                            for GUIDs? */
2431                         CHECK_BYTE_COUNT(16);
2432                         proto_tree_add_item(tree, hf_smb_server_guid,
2433                                 tvb, offset, 16, TRUE);
2434                         COUNT_BYTES(16);
2435
2436                         /* security blob */
2437                         /* If it runs past the end of the captured data, don't
2438                          * try to put all of it into the protocol tree as the
2439                          * raw security blob; we might get an exception on
2440                          * short frames and then we will not see anything at all
2441                          * of the security blob.
2442                          */
2443                         sbloblen=bc;
2444                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2445                                 sbloblen=tvb_length_remaining(tvb,offset);
2446                         }
2447                         blob_item = proto_tree_add_item(
2448                                 tree, hf_smb_security_blob,
2449                                 tvb, offset, sbloblen, TRUE);
2450
2451                         /*
2452                          * If Extended security and BCC == 16, then raw
2453                          * NTLMSSP is in use. We need to save this info
2454                          */
2455
2456                         if(bc){
2457                                 tvbuff_t *gssapi_tvb;
2458                                 proto_tree *gssapi_tree;
2459
2460                                 gssapi_tree = proto_item_add_subtree(
2461                                         blob_item, ett_smb_secblob);
2462
2463                                 /*
2464                                  * Set the reported length of this to
2465                                  * the reported length of the blob,
2466                                  * rather than the amount of data
2467                                  * available from the blob, so that
2468                                  * we'll throw the right exception if
2469                                  * it's too short.
2470                                  */
2471                                 gssapi_tvb = tvb_new_subset(
2472                                         tvb, offset, sbloblen, bc);
2473
2474                                 call_dissector(
2475                                         gssapi_handle, gssapi_tvb, pinfo,
2476                                         gssapi_tree);
2477
2478                                 if (si->ct)
2479                                   si->ct->raw_ntlmssp = 0;
2480
2481                                 COUNT_BYTES(bc);
2482                         }
2483                         else {
2484
2485                           /*
2486                            * There is no blob. We just have to make sure
2487                            * that subsequent routines know to call the
2488                            * right things ...
2489                            */
2490
2491                           if (si->ct)
2492                             si->ct->raw_ntlmssp = 1;
2493
2494                         }
2495                 }
2496                 break;
2497         }
2498
2499         END_OF_SMB
2500
2501         return offset;
2502 }
2503
2504
2505 static int
2506 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2507 {
2508         smb_info_t *si = pinfo->private_data;
2509         int dn_len;
2510         const char *dn;
2511         guint8 wc;
2512         guint16 bc;
2513
2514         DISSECTOR_ASSERT(si);
2515
2516         WORD_COUNT;
2517
2518         BYTE_COUNT;
2519
2520         /* buffer format */
2521         CHECK_BYTE_COUNT(1);
2522         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2523         COUNT_BYTES(1);
2524
2525         /* dir name */
2526         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2527                 FALSE, FALSE, &bc);
2528
2529         if((!pinfo->fd->flags.visited) && si->sip){
2530                 si->sip->extra_info_type=SMB_EI_FILENAME;
2531                 si->sip->extra_info=se_strdup(dn);
2532         }
2533
2534         if (dn == NULL)
2535                 goto endofcommand;
2536         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2537                 dn);
2538         COUNT_BYTES(dn_len);
2539
2540         if (check_col(pinfo->cinfo, COL_INFO)) {
2541                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2542                     format_text(dn, strlen(dn)));
2543         }
2544
2545         END_OF_SMB
2546
2547         return offset;
2548 }
2549
2550 static int
2551 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2552 {
2553         guint8 wc;
2554         guint16 bc;
2555         smb_info_t *si = pinfo->private_data;
2556         proto_item *item=NULL;
2557
2558         DISSECTOR_ASSERT(si);
2559
2560         if(si->sip && si->sip->extra_info_type==SMB_EI_FILENAME){
2561                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, si->sip->extra_info);
2562                 PROTO_ITEM_SET_GENERATED(item);
2563         }
2564
2565
2566         WORD_COUNT;
2567
2568         BYTE_COUNT;
2569
2570         END_OF_SMB
2571
2572         return offset;
2573 }
2574
2575 static int
2576 dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2577 {
2578         guint8 wc;
2579         guint16 bc;
2580         smb_info_t *si = pinfo->private_data;
2581         proto_item *item=NULL;
2582
2583         DISSECTOR_ASSERT(si);
2584
2585         if(si->sip && si->sip->extra_info_type==SMB_EI_RENAMEDATA){
2586                 smb_rename_saved_info_t *rni=si->sip->extra_info;
2587
2588                 item=proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2589                 PROTO_ITEM_SET_GENERATED(item);
2590                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2591                 PROTO_ITEM_SET_GENERATED(item);
2592         }
2593
2594
2595         WORD_COUNT;
2596
2597         BYTE_COUNT;
2598
2599         END_OF_SMB
2600
2601         return offset;
2602 }
2603
2604 static int
2605 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2606 {
2607         guint16 ec, bc;
2608         guint8 wc;
2609
2610         WORD_COUNT;
2611
2612         /* echo count */
2613         ec = tvb_get_letohs(tvb, offset);
2614         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2615         offset += 2;
2616
2617         BYTE_COUNT;
2618
2619         if (bc != 0) {
2620                 /* echo data */
2621                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2622                 COUNT_BYTES(bc);
2623         }
2624
2625         END_OF_SMB
2626
2627         return offset;
2628 }
2629
2630 static int
2631 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2632 {
2633         guint16 bc;
2634         guint8 wc;
2635
2636         WORD_COUNT;
2637
2638         /* echo sequence number */
2639         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2640         offset += 2;
2641
2642         BYTE_COUNT;
2643
2644         if (bc != 0) {
2645                 /* echo data */
2646                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2647                 COUNT_BYTES(bc);
2648         }
2649
2650         END_OF_SMB
2651
2652         return offset;
2653 }
2654
2655 static int
2656 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2657 {
2658         smb_info_t *si = pinfo->private_data;
2659         int an_len, pwlen;
2660         const char *an;
2661         guint8 wc;
2662         guint16 bc;
2663
2664         DISSECTOR_ASSERT(si);
2665
2666         WORD_COUNT;
2667
2668         BYTE_COUNT;
2669
2670         /* buffer format */
2671         CHECK_BYTE_COUNT(1);
2672         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2673         COUNT_BYTES(1);
2674
2675         /* Path */
2676         an = get_unicode_or_ascii_string(tvb, &offset,
2677                 si->unicode, &an_len, FALSE, FALSE, &bc);
2678         if (an == NULL)
2679                 goto endofcommand;
2680         proto_tree_add_string(tree, hf_smb_path, tvb,
2681                 offset, an_len, an);
2682         COUNT_BYTES(an_len);
2683
2684         if (check_col(pinfo->cinfo, COL_INFO)) {
2685                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2686                     format_text(an, strlen(an)));
2687         }
2688
2689         /* buffer format */
2690         CHECK_BYTE_COUNT(1);
2691         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2692         COUNT_BYTES(1);
2693
2694         /* password, ANSI */
2695         /* XXX - what if this runs past bc? */
2696         pwlen = tvb_strsize(tvb, offset);
2697         CHECK_BYTE_COUNT(pwlen);
2698         proto_tree_add_item(tree, hf_smb_password,
2699                 tvb, offset, pwlen, TRUE);
2700         COUNT_BYTES(pwlen);
2701
2702         /* buffer format */
2703         CHECK_BYTE_COUNT(1);
2704         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2705         COUNT_BYTES(1);
2706
2707         /* Service */
2708         /*
2709          * XXX - the SNIA CIFS spec "Strings that are never passed in
2710          * Unicode are: ... The service name string in the
2711          * Tree_Connect_AndX SMB".  Is that claim false?
2712          */
2713         an = get_unicode_or_ascii_string(tvb, &offset,
2714                 si->unicode, &an_len, FALSE, FALSE, &bc);
2715         if (an == NULL)
2716                 goto endofcommand;
2717         proto_tree_add_string(tree, hf_smb_service, tvb,
2718                 offset, an_len, an);
2719         COUNT_BYTES(an_len);
2720
2721         END_OF_SMB
2722
2723         return offset;
2724 }
2725
2726 static int
2727 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2728 {
2729         proto_item *item, *subitem;
2730         proto_tree *tree;
2731         smb_uid_t *smb_uid=NULL;
2732
2733         item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2734         tree=proto_item_add_subtree(item, ett_smb_uid);
2735
2736         smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
2737         if(smb_uid){
2738                 if(smb_uid->domain && smb_uid->account)
2739                         proto_item_append_text(item, "  (");
2740                 if(smb_uid->domain){
2741                         proto_item_append_text(item, "%s", smb_uid->domain);
2742                         subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2743                         PROTO_ITEM_SET_GENERATED(subitem);
2744                 }
2745                 if(smb_uid->account){
2746                         proto_item_append_text(item, "\\%s", smb_uid->account);
2747                         subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2748                         PROTO_ITEM_SET_GENERATED(subitem);
2749                 }
2750                 if(smb_uid->domain && smb_uid->account)
2751                         proto_item_append_text(item, ")");
2752                 if(smb_uid->logged_in>0){
2753                         subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2754                         PROTO_ITEM_SET_GENERATED(subitem);
2755                 }
2756                 if(smb_uid->logged_out>0){
2757                         subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2758                         PROTO_ITEM_SET_GENERATED(subitem);
2759                 }
2760         }
2761         offset += 2;
2762
2763         return offset;
2764 }
2765
2766 static int
2767 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
2768 {
2769         smb_info_t *si = pinfo->private_data;
2770         proto_item *it;
2771         proto_tree *tr;
2772         smb_tid_info_t *tid_info=NULL;
2773
2774         DISSECTOR_ASSERT(si);
2775
2776         /* tid */
2777         it=proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2778         tr=proto_item_add_subtree(it, ett_smb_tid);
2779         offset += 2;
2780
2781         if((!pinfo->fd->flags.visited) && is_created){
2782                 tid_info=se_alloc(sizeof(smb_tid_info_t));
2783                 tid_info->opened_in=pinfo->fd->num;
2784                 tid_info->closed_in=0;
2785                 tid_info->type=SMB_FID_TYPE_UNKNOWN;
2786                 if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
2787                         tid_info->filename=si->sip->extra_info;
2788                 } else {
2789                         tid_info->filename=NULL;
2790                 }
2791                 se_tree_insert32(si->ct->tid_tree, tid, tid_info);
2792         }
2793
2794         if(!tid_info){
2795                 tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
2796         }
2797         if(!tid_info){
2798                 return offset;
2799         }
2800
2801         if((!pinfo->fd->flags.visited) && is_closed){
2802                 tid_info->closed_in=pinfo->fd->num;
2803         }
2804
2805         if(tid_info->opened_in){
2806                 if(tid_info->filename){
2807                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2808
2809                         it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2810                         PROTO_ITEM_SET_GENERATED(it);
2811                 }
2812
2813                 it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2814                 PROTO_ITEM_SET_GENERATED(it);
2815         }
2816         if(tid_info->closed_in){
2817                 it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2818                 PROTO_ITEM_SET_GENERATED(it);
2819         }
2820
2821
2822         return offset;
2823 }
2824
2825 static int
2826 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2827 {
2828         guint8 wc;
2829         guint16 bc;
2830
2831         WORD_COUNT;
2832
2833         /* Maximum Buffer Size */
2834         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2835         offset += 2;
2836
2837         /* tid */
2838         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE);
2839
2840         BYTE_COUNT;
2841
2842         END_OF_SMB
2843
2844         return offset;
2845 }
2846
2847
2848 static const true_false_string tfs_of_create = {
2849         "Create file if it does not exist",
2850         "Fail if file does not exist"
2851 };
2852 static const value_string of_open[] = {
2853         { 0,            "Fail if file exists"},
2854         { 1,            "Open file if it exists"},
2855         { 2,            "Truncate file if it exists"},
2856         {0, NULL}
2857 };
2858 static int
2859 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2860 {
2861         guint16 mask;
2862         proto_item *item = NULL;
2863         proto_tree *tree = NULL;
2864
2865         mask = tvb_get_letohs(tvb, offset);
2866
2867         if(parent_tree){
2868                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2869                         "Open Function: 0x%04x", mask);
2870                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2871         }
2872
2873         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2874                 tvb, offset, 2, mask);
2875         proto_tree_add_uint(tree, hf_smb_open_function_open,
2876                 tvb, offset, 2, mask);
2877
2878         offset += 2;
2879
2880         return offset;
2881 }
2882
2883
2884 static const true_false_string tfs_mf_file = {
2885         "Target must be a file",
2886         "Target needn't be a file"
2887 };
2888 static const true_false_string tfs_mf_dir = {
2889         "Target must be a directory",
2890         "Target needn't be a directory"
2891 };
2892 static const true_false_string tfs_mf_verify = {
2893         "MUST verify all writes",
2894         "Don't have to verify writes"
2895 };
2896 static int
2897 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2898 {
2899         guint16 mask;
2900         proto_item *item = NULL;
2901         proto_tree *tree = NULL;
2902
2903         mask = tvb_get_letohs(tvb, offset);
2904
2905         if(parent_tree){
2906                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2907                         "Flags: 0x%04x", mask);
2908                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2909         }
2910
2911         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2912                 tvb, offset, 2, mask);
2913         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2914                 tvb, offset, 2, mask);
2915         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2916                 tvb, offset, 2, mask);
2917
2918         offset += 2;
2919
2920         return offset;
2921 }
2922
2923 static const true_false_string tfs_cf_mode = {
2924         "ASCII",
2925         "Binary"
2926 };
2927 static const true_false_string tfs_cf_tree_copy = {
2928         "Copy is a tree copy",
2929         "Copy is a file copy"
2930 };
2931 static const true_false_string tfs_cf_ea_action = {
2932         "Fail copy",
2933         "Discard EAs"
2934 };
2935 static int
2936 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2937 {
2938         guint16 mask;
2939         proto_item *item = NULL;
2940         proto_tree *tree = NULL;
2941
2942         mask = tvb_get_letohs(tvb, offset);
2943
2944         if(parent_tree){
2945                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2946                         "Flags: 0x%04x", mask);
2947                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2948         }
2949
2950         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2951                 tvb, offset, 2, mask);
2952         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2953                 tvb, offset, 2, mask);
2954         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2955                 tvb, offset, 2, mask);
2956         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2957                 tvb, offset, 2, mask);
2958         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2959                 tvb, offset, 2, mask);
2960         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2961                 tvb, offset, 2, mask);
2962         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2963                 tvb, offset, 2, mask);
2964
2965         offset += 2;
2966
2967         return offset;
2968 }
2969
2970 static int
2971 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2972 {
2973         smb_info_t *si = pinfo->private_data;
2974         int fn_len;
2975         guint16 tid;
2976         guint16 bc;
2977         guint8 wc;
2978         const char *fn;
2979
2980         DISSECTOR_ASSERT(si);
2981
2982         WORD_COUNT;
2983
2984         /* tid */
2985         tid = tvb_get_letohs(tvb, offset);
2986         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2987
2988         /* open function */
2989         offset = dissect_open_function(tvb, tree, offset);
2990
2991         /* move flags */
2992         offset = dissect_move_flags(tvb, tree, offset);
2993
2994         BYTE_COUNT;
2995
2996         /* buffer format */
2997         CHECK_BYTE_COUNT(1);
2998         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2999         COUNT_BYTES(1);
3000
3001         /* file name */
3002         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3003                 FALSE, FALSE, &bc);
3004         if (fn == NULL)
3005                 goto endofcommand;
3006         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3007                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
3008         COUNT_BYTES(fn_len);
3009
3010         if (check_col(pinfo->cinfo, COL_INFO)) {
3011                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3012                     format_text(fn, strlen(fn)));
3013         }
3014
3015         /* buffer format */
3016         CHECK_BYTE_COUNT(1);
3017         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3018         COUNT_BYTES(1);
3019
3020         /* file name */
3021         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3022                 FALSE, FALSE, &bc);
3023         if (fn == NULL)
3024                 goto endofcommand;
3025         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3026                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
3027         COUNT_BYTES(fn_len);
3028
3029         if (check_col(pinfo->cinfo, COL_INFO)) {
3030                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3031                     format_text(fn, strlen(fn)));
3032         }
3033
3034         END_OF_SMB
3035
3036         return offset;
3037 }
3038
3039 static int
3040 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3041 {
3042         smb_info_t *si = pinfo->private_data;
3043         int fn_len;
3044         guint16 tid;
3045         guint16 bc;
3046         guint8 wc;
3047         const char *fn;
3048
3049         DISSECTOR_ASSERT(si);
3050
3051         WORD_COUNT;
3052
3053         /* tid */
3054         tid = tvb_get_letohs(tvb, offset);
3055         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
3056
3057         /* open function */
3058         offset = dissect_open_function(tvb, tree, offset);
3059
3060         /* copy flags */
3061         offset = dissect_copy_flags(tvb, tree, offset);
3062
3063         BYTE_COUNT;
3064
3065         /* buffer format */
3066         CHECK_BYTE_COUNT(1);
3067         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3068         COUNT_BYTES(1);
3069
3070         /* file name */
3071         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3072                 FALSE, FALSE, &bc);
3073         if (fn == NULL)
3074                 goto endofcommand;
3075         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3076                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
3077         COUNT_BYTES(fn_len);
3078
3079         if (check_col(pinfo->cinfo, COL_INFO)) {
3080                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3081                     format_text(fn, strlen(fn)));
3082         }
3083
3084         /* buffer format */
3085         CHECK_BYTE_COUNT(1);
3086         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3087         COUNT_BYTES(1);
3088
3089         /* file name */
3090         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3091                 FALSE, FALSE, &bc);
3092         if (fn == NULL)
3093                 goto endofcommand;
3094         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3095                 fn_len, fn, "Destination File Name: %s",
3096                 format_text(fn, strlen(fn)));
3097         COUNT_BYTES(fn_len);
3098
3099         if (check_col(pinfo->cinfo, COL_INFO)) {
3100                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3101         }
3102
3103         END_OF_SMB
3104
3105         return offset;
3106 }
3107
3108 static int
3109 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3110 {
3111         smb_info_t *si = pinfo->private_data;
3112         int fn_len;
3113         const char *fn;
3114         guint8 wc;
3115         guint16 bc;
3116
3117         DISSECTOR_ASSERT(si);
3118
3119         WORD_COUNT;
3120
3121         /* # of files moved */
3122         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
3123         offset += 2;
3124
3125         BYTE_COUNT;
3126
3127         /* buffer format */
3128         CHECK_BYTE_COUNT(1);
3129         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3130         COUNT_BYTES(1);
3131
3132         /* file name */
3133         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3134                 FALSE, FALSE, &bc);
3135         if (fn == NULL)
3136                 goto endofcommand;
3137         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3138                 fn);
3139         COUNT_BYTES(fn_len);
3140
3141         END_OF_SMB
3142
3143         return offset;
3144 }
3145
3146 static int
3147 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3148 {
3149         smb_info_t *si = pinfo->private_data;
3150         int fn_len;
3151         const char *fn;
3152         guint8 wc;
3153         guint16 bc;
3154
3155         DISSECTOR_ASSERT(si);
3156
3157         WORD_COUNT;
3158
3159         /* desired access */
3160         offset = dissect_access(tvb, tree, offset, "Desired");
3161
3162         /* Search Attributes */
3163         offset = dissect_search_attributes(tvb, tree, offset);
3164
3165         BYTE_COUNT;
3166
3167         /* buffer format */
3168         CHECK_BYTE_COUNT(1);
3169         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3170         COUNT_BYTES(1);
3171
3172         /* file name */
3173         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3174                 FALSE, FALSE, &bc);
3175         if (fn == NULL)
3176                 goto endofcommand;
3177         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3178                 fn);
3179         COUNT_BYTES(fn_len);
3180
3181         if (check_col(pinfo->cinfo, COL_INFO)) {
3182                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3183                     format_text(fn, strlen(fn)));
3184         }
3185
3186         END_OF_SMB
3187
3188         return offset;
3189 }
3190
3191
3192
3193 static int
3194 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3195     int len, guint32 mask)
3196 {
3197         proto_item *item = NULL;
3198         proto_tree *tree = NULL;
3199
3200         if(parent_tree){
3201                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3202
3203                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3204         }
3205
3206         /*
3207          * XXX - it's 0x00000016 in at least one capture, but
3208          * Network Monitor doesn't say what the 0x00000010 bit is.
3209          * Does the Win32 API documentation, or NT Native API book,
3210          * suggest anything?
3211          *
3212          * That is the extended response desired bit ... RJS, from Samba
3213          * Well, maybe. Samba thinks it is, and uses it to encode
3214          * OpLock granted as the high order bit of the Action field
3215          * in the response. However, Windows does not do that. Or at least
3216          * Win2K doesn't.
3217          */
3218         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3219                                tvb, offset, len, mask);
3220         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3221                 tvb, offset, len, mask);
3222         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3223                 tvb, offset, len, mask);
3224         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3225                 tvb, offset, len, mask);
3226
3227         offset += len;
3228
3229         return offset;
3230 }
3231
3232 /* FIXME: need to call dissect_nt_access_mask() instead */
3233 static int
3234 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3235     int offset, int len, guint32 mask)
3236 {
3237         proto_item *item;
3238         proto_tree *tree;
3239
3240         if(parent_tree){
3241                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3242                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3243
3244                 /*
3245                  * Some of these bits come from
3246                  *
3247                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3248                  *
3249                  * and others come from the section on ZwOpenFile in "Windows(R)
3250                  * NT(R)/2000 Native API Reference".
3251                  */
3252                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3253                         tvb, offset, len, mask);
3254                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3255                         tvb, offset, len, mask);
3256                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3257                         tvb, offset, len, mask);
3258                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3259                         tvb, offset, len, mask);
3260                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3261                         tvb, offset, len, mask);
3262                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3263                         tvb, offset, len, mask);
3264                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3265                         tvb, offset, len, mask);
3266                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3267                         tvb, offset, len, mask);
3268                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3269                         tvb, offset, len, mask);
3270                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3271                         tvb, offset, len, mask);
3272                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3273                         tvb, offset, len, mask);
3274                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3275                         tvb, offset, len, mask);
3276                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3277                         tvb, offset, len, mask);
3278                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3279                         tvb, offset, len, mask);
3280                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3281                         tvb, offset, len, mask);
3282                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3283                         tvb, offset, len, mask);
3284                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3285                         tvb, offset, len, mask);
3286                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3287                         tvb, offset, len, mask);
3288                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3289                         tvb, offset, len, mask);
3290                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3291                         tvb, offset, len, mask);
3292         }
3293         offset += len;
3294
3295         return offset;
3296 }
3297
3298 int
3299 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3300 {
3301         guint32 mask;
3302
3303         mask = tvb_get_letohl(tvb, offset);
3304
3305         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3306
3307         return offset;
3308 }
3309
3310
3311 #define SHARE_ACCESS_DELETE     0x00000004
3312 #define SHARE_ACCESS_WRITE      0x00000002
3313 #define SHARE_ACCESS_READ       0x00000001
3314
3315 static int
3316 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3317     int offset, int len, guint32 mask)
3318 {
3319         proto_item *item;
3320         proto_tree *tree;
3321
3322         if(parent_tree){
3323                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3324                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3325
3326                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3327                         tvb, offset, len, mask);
3328                 if(mask&SHARE_ACCESS_DELETE){
3329                         proto_item_append_text(item, " SHARE_DELETE");
3330                 }
3331
3332                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3333                         tvb, offset, len, mask);
3334                 if(mask&SHARE_ACCESS_WRITE){
3335                         proto_item_append_text(item, " SHARE_WRITE");
3336                 }
3337
3338                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3339                         tvb, offset, len, mask);
3340                 if(mask&SHARE_ACCESS_READ){
3341                         proto_item_append_text(item, " SHARE_READ");
3342                 }
3343         }
3344
3345         offset += len;
3346
3347         return offset;
3348 }
3349
3350 int
3351 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3352 {
3353         guint32 mask;
3354
3355         mask = tvb_get_letohl(tvb, offset);
3356
3357         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3358
3359         return offset;
3360 }
3361
3362
3363 static int
3364 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3365     int offset, int len, guint32 mask)
3366 {
3367         proto_item *item;
3368         proto_tree *tree;
3369
3370         if(parent_tree){
3371                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3372                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3373
3374                 /*
3375                  * From
3376                  *
3377                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3378                  */
3379                  proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3380                         tvb, offset, len, mask);
3381                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3382                         tvb, offset, len, mask);
3383                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3384                         tvb, offset, len, mask);
3385                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3386                         tvb, offset, len, mask);
3387                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3388                         tvb, offset, len, mask);
3389                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3390                         tvb, offset, len, mask);
3391                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3392                         tvb, offset, len, mask);
3393                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3394                         tvb, offset, len, mask);
3395                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3396                         tvb, offset, len, mask);
3397                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3398                         tvb, offset, len, mask);
3399                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3400                         tvb, offset, len, mask);
3401                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3402                         tvb, offset, len, mask);
3403                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3404                         tvb, offset, len, mask);
3405                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3406                         tvb, offset, len, mask);
3407                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3408                         tvb, offset, len, mask);
3409                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3410                         tvb, offset, len, mask);
3411                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3412                         tvb, offset, len, mask);
3413                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3414                         tvb, offset, len, mask);
3415                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3416                         tvb, offset, len, mask);
3417                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3418                         tvb, offset, len, mask);
3419         }
3420         offset += len;
3421
3422         return offset;
3423 }
3424
3425 int
3426 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3427 {
3428         guint32 mask;
3429
3430         mask = tvb_get_letohl(tvb, offset);
3431
3432         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3433
3434         return offset;
3435 }
3436
3437
3438 /* fids are scoped by tcp session */
3439 smb_fid_info_t *
3440 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3441     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
3442 {
3443         smb_info_t *si = pinfo->private_data;
3444         smb_saved_info_t *sip = si->sip;
3445         proto_item *it;
3446         proto_tree *tr;
3447         smb_fid_info_t *fid_info=NULL;
3448
3449         DISSECTOR_ASSERT(si);
3450
3451         it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3452         if(is_generated){
3453                 PROTO_ITEM_SET_GENERATED(it);
3454         }
3455         tr=proto_item_add_subtree(it, ett_smb_fid);
3456         if (check_col(pinfo->cinfo, COL_INFO))
3457                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3458
3459         if((!pinfo->fd->flags.visited) && is_created){
3460                 fid_info=se_alloc(sizeof(smb_fid_info_t));
3461                 fid_info->opened_in=pinfo->fd->num;
3462                 fid_info->closed_in=0;
3463                 fid_info->type=SMB_FID_TYPE_UNKNOWN;
3464                 if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
3465                         fid_info->fsi=si->sip->extra_info;
3466                 } else {
3467                         fid_info->fsi=NULL;
3468                 }
3469
3470                 se_tree_insert32(si->ct->fid_tree, fid, fid_info);
3471         }
3472
3473         if(!fid_info){
3474                 fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
3475         }
3476         if(!fid_info){
3477                 return NULL;
3478         }
3479
3480         /* Store the fid in the transaction structure and remember if
3481            it was in the request or in the reply we saw it
3482          */
3483         if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3484                 sip->fid=fid;
3485                 if(si->request){
3486                         sip->fid_seen_in_request=TRUE;
3487                 } else {
3488                         sip->fid_seen_in_request=FALSE;
3489                 }
3490         }
3491
3492         if((!pinfo->fd->flags.visited) && is_closed){
3493                 fid_info->closed_in=pinfo->fd->num;
3494         }
3495
3496         if(fid_info->opened_in){
3497                 it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3498                 PROTO_ITEM_SET_GENERATED(it);
3499         }
3500
3501         if(fid_info->closed_in){
3502                 it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3503                 PROTO_ITEM_SET_GENERATED(it);
3504         }
3505
3506
3507         if(fid_info->opened_in){
3508                 if(fid_info->fsi && fid_info->fsi->filename){
3509                         it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3510                         PROTO_ITEM_SET_GENERATED(it);
3511                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3512                         dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3513                         dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3514                         dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3515                         dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3516                         dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3517                         it=proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3518                         PROTO_ITEM_SET_GENERATED(it);
3519                 }
3520         }
3521
3522         return fid_info;
3523 }
3524
3525 static int
3526 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3527 {
3528         guint8 wc;
3529         guint16 bc;
3530         guint16 fid;
3531
3532         WORD_COUNT;
3533
3534         /* fid */
3535         fid = tvb_get_letohs(tvb, offset);
3536         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3537         offset += 2;
3538
3539         /* File Attributes */
3540         offset = dissect_file_attributes(tvb, tree, offset, 2);
3541
3542         /* last write time */
3543         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3544
3545         /* File Size */
3546         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3547         offset += 4;
3548
3549         /* granted access */
3550         offset = dissect_access(tvb, tree, offset, "Granted");
3551
3552         BYTE_COUNT;
3553
3554         END_OF_SMB
3555
3556         return offset;
3557 }
3558
3559 static int
3560 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3561 {
3562         guint8 wc;
3563         guint16 bc;
3564         guint16 fid;
3565
3566         WORD_COUNT;
3567
3568         /* fid */
3569         fid = tvb_get_letohs(tvb, offset);
3570         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3571         offset += 2;
3572
3573         BYTE_COUNT;
3574
3575         END_OF_SMB
3576
3577         return offset;
3578 }
3579
3580 static int
3581 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3582 {
3583         guint8 wc;
3584         guint16 bc;
3585         guint16 fid;
3586
3587         WORD_COUNT;
3588
3589         /* fid */
3590         fid = tvb_get_letohs(tvb, offset);
3591         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3592         offset += 2;
3593
3594         BYTE_COUNT;
3595
3596         END_OF_SMB
3597
3598         return offset;
3599 }
3600
3601 static int
3602 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3603 {
3604         guint8 wc;
3605         guint16 bc;
3606         guint16 fid;
3607
3608         WORD_COUNT;
3609
3610         /* fid */
3611         fid = tvb_get_letohs(tvb, offset);
3612         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3613         offset += 2;
3614
3615         BYTE_COUNT;
3616
3617         END_OF_SMB
3618
3619         return offset;
3620 }
3621
3622 static int
3623 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3624 {
3625         guint8 wc;
3626         guint16 bc;
3627         guint16 fid;
3628
3629         WORD_COUNT;
3630
3631         /* fid */
3632         fid = tvb_get_letohs(tvb, offset);
3633         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3634         offset += 2;
3635
3636         BYTE_COUNT;
3637
3638         END_OF_SMB
3639
3640         return offset;
3641 }
3642
3643 static int
3644 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3645 {
3646         guint8 wc;
3647         guint16 bc;
3648         guint16 fid;
3649
3650         WORD_COUNT;
3651
3652         /* fid */
3653         fid = tvb_get_letohs(tvb, offset);
3654         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3655         offset += 2;
3656
3657         BYTE_COUNT;
3658
3659         END_OF_SMB
3660
3661         return offset;
3662 }
3663
3664 static int
3665 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3666 {
3667         guint8 wc;
3668         guint16 bc;
3669         guint16 fid;
3670
3671         WORD_COUNT;
3672
3673         /* fid */
3674         fid = tvb_get_letohs(tvb, offset);
3675         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3676         offset += 2;
3677
3678         BYTE_COUNT;
3679
3680         END_OF_SMB
3681
3682         return offset;
3683 }
3684
3685 static int
3686 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3687 {
3688         smb_info_t *si = pinfo->private_data;
3689         int fn_len;
3690         const char *fn;
3691         guint8 wc;
3692         guint16 bc;
3693
3694         DISSECTOR_ASSERT(si);
3695
3696         WORD_COUNT;
3697
3698         /* file attributes */
3699         offset = dissect_file_attributes(tvb, tree, offset, 2);
3700
3701         /* creation time */
3702         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3703
3704         BYTE_COUNT;
3705
3706         /* buffer format */
3707         CHECK_BYTE_COUNT(1);
3708         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3709         COUNT_BYTES(1);
3710
3711         /* File Name */
3712         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3713                 FALSE, FALSE, &bc);
3714         if (fn == NULL)
3715                 goto endofcommand;
3716         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3717                 fn);
3718         COUNT_BYTES(fn_len);
3719
3720         if (check_col(pinfo->cinfo, COL_INFO)) {
3721                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3722                     format_text(fn, strlen(fn)));
3723         }
3724
3725         END_OF_SMB
3726
3727         return offset;
3728 }
3729
3730 static int
3731 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3732 {
3733         guint8 wc;
3734         guint16 bc, fid;
3735
3736         WORD_COUNT;
3737
3738         /* fid */
3739         fid = tvb_get_letohs(tvb, offset);
3740         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3741         offset += 2;
3742
3743         /* last write time */
3744         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3745
3746         BYTE_COUNT;
3747
3748         END_OF_SMB
3749
3750         return offset;
3751 }
3752
3753 static int
3754 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3755 {
3756         smb_info_t *si = pinfo->private_data;
3757         int fn_len;
3758         const char *fn;
3759         guint8 wc;
3760         guint16 bc;
3761
3762         DISSECTOR_ASSERT(si);
3763
3764         WORD_COUNT;
3765
3766         /* search attributes */
3767         offset = dissect_search_attributes(tvb, tree, offset);
3768
3769         BYTE_COUNT;
3770
3771         /* buffer format */
3772         CHECK_BYTE_COUNT(1);
3773         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3774         COUNT_BYTES(1);
3775
3776         /* file name */
3777         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3778                 FALSE, FALSE, &bc);
3779
3780         if((!pinfo->fd->flags.visited) && si->sip){
3781                 si->sip->extra_info_type=SMB_EI_FILENAME;
3782                 si->sip->extra_info=se_strdup(fn);
3783         }
3784
3785         if (fn == NULL)
3786                 goto endofcommand;
3787         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3788                 fn);
3789         COUNT_BYTES(fn_len);
3790
3791         if (check_col(pinfo->cinfo, COL_INFO)) {
3792                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3793                     format_text(fn, strlen(fn)));
3794         }
3795
3796         END_OF_SMB
3797
3798         return offset;
3799 }
3800
3801 static int
3802 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3803 {
3804         smb_info_t *si = pinfo->private_data;
3805         int fn_len;
3806         const char *fn, *old_name=NULL, *new_name=NULL;
3807         guint8 wc;
3808         guint16 bc;
3809         smb_rename_saved_info_t *rni=NULL;
3810
3811         DISSECTOR_ASSERT(si);
3812
3813         WORD_COUNT;
3814
3815         /* search attributes */
3816         offset = dissect_search_attributes(tvb, tree, offset);
3817
3818         BYTE_COUNT;
3819
3820         /* buffer format */
3821         CHECK_BYTE_COUNT(1);
3822         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3823         COUNT_BYTES(1);
3824
3825         /* old file name */
3826         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3827                 FALSE, FALSE, &bc);
3828         if (fn == NULL)
3829                 goto endofcommand;
3830         old_name=fn;
3831         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3832                 fn);
3833         COUNT_BYTES(fn_len);
3834
3835         if (check_col(pinfo->cinfo, COL_INFO)) {
3836                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3837                     format_text(fn, strlen(fn)));
3838         }
3839
3840         /* buffer format */
3841         CHECK_BYTE_COUNT(1);
3842         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3843         COUNT_BYTES(1);
3844
3845         /* file name */
3846         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3847                 FALSE, FALSE, &bc);
3848         if (fn == NULL)
3849                 goto endofcommand;
3850         new_name=fn;
3851         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3852                 fn);
3853         COUNT_BYTES(fn_len);
3854
3855         if (check_col(pinfo->cinfo, COL_INFO)) {
3856                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3857                     format_text(fn, strlen(fn)));
3858         }
3859
3860         END_OF_SMB
3861
3862         /* save the offset/len for this transaction */
3863         if(si->sip && !pinfo->fd->flags.visited){
3864                 rni=se_alloc(sizeof(smb_rename_saved_info_t));
3865                 rni->old_name=se_strdup(old_name);
3866                 rni->new_name=se_strdup(new_name);
3867
3868                 si->sip->extra_info_type=SMB_EI_RENAMEDATA;
3869                 si->sip->extra_info=rni;
3870         }
3871
3872         return offset;
3873 }
3874
3875 static int
3876 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3877 {
3878         smb_info_t *si = pinfo->private_data;
3879         int fn_len;
3880         const char *fn;
3881         guint8 wc;
3882         guint16 bc;
3883
3884         DISSECTOR_ASSERT(si);
3885
3886         WORD_COUNT;
3887
3888         /* search attributes */
3889         offset = dissect_search_attributes(tvb, tree, offset);
3890
3891         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3892         offset += 2;
3893
3894         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3895         offset += 4;
3896
3897         BYTE_COUNT;
3898
3899         /* buffer format */
3900         CHECK_BYTE_COUNT(1);
3901         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3902         COUNT_BYTES(1);
3903
3904         /* old file name */
3905         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3906                 FALSE, FALSE, &bc);
3907         if (fn == NULL)
3908                 goto endofcommand;
3909         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3910                 fn);
3911         COUNT_BYTES(fn_len);
3912
3913         if (check_col(pinfo->cinfo, COL_INFO)) {
3914                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3915                     format_text(fn, strlen(fn)));
3916         }
3917
3918         /* buffer format */
3919         CHECK_BYTE_COUNT(1);
3920         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3921         COUNT_BYTES(1);
3922
3923         /* file name */
3924         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3925                 FALSE, FALSE, &bc);
3926         if (fn == NULL)
3927                 goto endofcommand;
3928         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3929                 fn);
3930         COUNT_BYTES(fn_len);
3931
3932         if (check_col(pinfo->cinfo, COL_INFO)) {
3933                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3934                     format_text(fn, strlen(fn)));
3935         }
3936
3937         END_OF_SMB
3938
3939         return offset;
3940 }
3941
3942
3943 static int
3944 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3945 {
3946         smb_info_t *si = pinfo->private_data;
3947         guint16 bc;
3948         guint8 wc;
3949         const char *fn;
3950         int fn_len;
3951
3952         DISSECTOR_ASSERT(si);
3953
3954         WORD_COUNT;
3955
3956         BYTE_COUNT;
3957
3958         /* Buffer Format */
3959         CHECK_BYTE_COUNT(1);
3960         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3961         COUNT_BYTES(1);
3962
3963         /* File Name */
3964         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3965                 FALSE, FALSE, &bc);
3966         if (fn == NULL)
3967                 goto endofcommand;
3968         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3969                 fn);
3970         COUNT_BYTES(fn_len);
3971
3972         if (check_col(pinfo->cinfo, COL_INFO)) {
3973                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3974                     format_text(fn, strlen(fn)));
3975         }
3976
3977         END_OF_SMB
3978
3979         return offset;
3980 }
3981
3982 static int
3983 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3984 {
3985         guint16 bc;
3986         guint8 wc;
3987
3988         WORD_COUNT;
3989
3990         /* File Attributes */
3991         offset = dissect_file_attributes(tvb, tree, offset, 2);
3992
3993         /* Last Write Time */
3994         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3995
3996         /* File Size */
3997         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3998         offset += 4;
3999
4000         /* 10 reserved bytes */
4001         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4002         offset += 10;
4003
4004         BYTE_COUNT;
4005
4006         END_OF_SMB
4007
4008         return offset;
4009 }
4010
4011 static int
4012 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4013 {
4014         smb_info_t *si = pinfo->private_data;
4015         int fn_len;
4016         const char *fn;
4017         guint8 wc;
4018         guint16 bc;
4019
4020         DISSECTOR_ASSERT(si);
4021
4022         WORD_COUNT;
4023
4024         /* file attributes */
4025         offset = dissect_file_attributes(tvb, tree, offset, 2);
4026
4027         /* last write time */
4028         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4029
4030         /* 10 reserved bytes */
4031         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4032         offset += 10;
4033
4034         BYTE_COUNT;
4035
4036         /* buffer format */
4037         CHECK_BYTE_COUNT(1);
4038         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4039         COUNT_BYTES(1);
4040
4041         /* file name */
4042         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4043                 FALSE, FALSE, &bc);
4044         if (fn == NULL)
4045                 goto endofcommand;
4046         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4047                 fn);
4048         COUNT_BYTES(fn_len);
4049
4050         if (check_col(pinfo->cinfo, COL_INFO)) {
4051                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4052                     format_text(fn, strlen(fn)));
4053         }
4054
4055         END_OF_SMB
4056
4057         return offset;
4058 }
4059
4060 static int
4061 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4062 {
4063         guint8 wc;
4064         guint16 cnt=0, bc;
4065         guint32 ofs=0;
4066         unsigned int fid;
4067
4068         WORD_COUNT;
4069
4070         /* fid */
4071         fid = tvb_get_letohs(tvb, offset);
4072         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
4073         offset += 2;
4074
4075         /* read count */
4076         cnt = tvb_get_letohs(tvb, offset);
4077         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4078         offset += 2;
4079
4080         /* offset */
4081         ofs = tvb_get_letohl(tvb, offset);
4082         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4083         offset += 4;
4084
4085         if (check_col(pinfo->cinfo, COL_INFO))
4086                 col_append_fstr(pinfo->cinfo, COL_INFO,
4087                                 ", %u byte%s at offset %u", cnt,
4088                                 (cnt == 1) ? "" : "s", ofs);
4089
4090         /* remaining */
4091         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4092         offset += 2;
4093
4094         BYTE_COUNT;
4095
4096         END_OF_SMB
4097
4098         return offset;
4099 }
4100
4101 int
4102 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4103 {
4104         int tvblen;
4105
4106         if(bc>datalen){
4107                 /* We have some initial padding bytes. */
4108                 /* XXX - use the data offset here instead? */
4109                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4110                         TRUE);
4111                 offset += bc-datalen;
4112                 bc = datalen;
4113         }
4114         tvblen = tvb_length_remaining(tvb, offset);
4115         if(bc>tvblen){
4116                 proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %u bytes", tvblen, bc);
4117                 offset += tvblen;
4118         } else {
4119                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
4120                 offset += bc;
4121         }
4122         return offset;
4123 }
4124
4125 static int
4126 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4127     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4128 {
4129         int tvblen;
4130         tvbuff_t *dcerpc_tvb;
4131
4132         if(bc>datalen){
4133                 /* We have some initial padding bytes. */
4134                 /* XXX - use the data offset here instead? */
4135                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4136                         TRUE);
4137                 offset += bc-datalen;
4138                 bc = datalen;
4139         }
4140         tvblen = tvb_length_remaining(tvb, offset);
4141         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4142         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4143         if(bc>tvblen)
4144                 offset += tvblen;
4145         else
4146                 offset += bc;
4147         return offset;
4148 }
4149
4150 /*
4151  * transporting DCERPC over SMB seems to be implemented in various
4152  * ways. We might just assume it can be done by an almost random
4153  * mix of Trans/Read/Write calls
4154  *
4155  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4156  * and let him sort them out
4157  */
4158 static int
4159 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4160     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4161     guint16 datalen, guint32 ofs, guint16 fid)
4162 {
4163         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4164
4165         DISSECTOR_ASSERT(si);
4166
4167         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
4168                 /* dcerpc call */
4169                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4170                     top_tree, offset, bc, datalen, fid);
4171         } else {
4172                 /* ordinary file data */
4173                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4174         }
4175 }
4176
4177 static int
4178 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4179 {
4180         guint16 cnt=0, bc;
4181         guint8 wc;
4182         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4183         int fid=0;
4184
4185         DISSECTOR_ASSERT(si);
4186
4187         WORD_COUNT;
4188
4189         /* read count */
4190         cnt = tvb_get_letohs(tvb, offset);
4191         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4192         offset += 2;
4193
4194         /* 8 reserved bytes */
4195         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4196         offset += 8;
4197         BYTE_COUNT;
4198
4199         /* buffer format */
4200         CHECK_BYTE_COUNT(1);
4201         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4202         COUNT_BYTES(1);
4203
4204         /* data len */
4205         CHECK_BYTE_COUNT(2);
4206         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4207         COUNT_BYTES(2);
4208
4209         /* file data, might be DCERPC on a pipe */
4210         if(bc){
4211                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4212                     top_tree, offset, bc, bc, 0, (guint16) fid);
4213                 bc = 0;
4214         }
4215
4216         END_OF_SMB
4217
4218         return offset;
4219 }
4220
4221 static int
4222 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4223 {
4224         guint16 cnt, bc;
4225         guint8 wc;
4226
4227         WORD_COUNT;
4228
4229         /* read count */
4230         cnt = tvb_get_letohs(tvb, offset);
4231         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4232         offset += 2;
4233
4234         /* 8 reserved bytes */
4235         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4236         offset += 8;
4237
4238         BYTE_COUNT;
4239
4240         /* buffer format */
4241         CHECK_BYTE_COUNT(1);
4242         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4243         COUNT_BYTES(1);
4244
4245         /* data len */
4246         CHECK_BYTE_COUNT(2);
4247         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4248         COUNT_BYTES(2);
4249
4250         END_OF_SMB
4251
4252         return offset;
4253 }
4254
4255 typedef struct _rw_info_t {
4256         guint32 offset;
4257         guint32 len;
4258         guint16 fid;
4259 } rw_info_t;
4260
4261
4262 static int
4263 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4264 {
4265         guint32 ofs=0;
4266         guint16 cnt=0, bc, fid=0;
4267         guint8 wc;
4268         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4269         rw_info_t *rwi=NULL;
4270
4271         DISSECTOR_ASSERT(si);
4272
4273         WORD_COUNT;
4274
4275         /* fid */
4276         fid = tvb_get_letohs(tvb, offset);
4277         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4278         offset += 2;
4279
4280         /* write count */
4281         cnt = tvb_get_letohs(tvb, offset);
4282         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4283         offset += 2;
4284
4285         /* offset */
4286         ofs = tvb_get_letohl(tvb, offset);
4287         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4288         offset += 4;
4289
4290         if (check_col(pinfo->cinfo, COL_INFO))
4291                 col_append_fstr(pinfo->cinfo, COL_INFO,
4292                                 ", %u byte%s at offset %u", cnt,
4293                                 (cnt == 1) ? "" : "s", ofs);
4294
4295         /* save the offset/len for this transaction */
4296         if(si->sip && !pinfo->fd->flags.visited){
4297                 rwi=se_alloc(sizeof(rw_info_t));
4298                 rwi->offset=ofs;
4299                 rwi->len=cnt;
4300                 rwi->fid=fid;
4301
4302                 si->sip->extra_info_type=SMB_EI_RWINFO;
4303                 si->sip->extra_info=rwi;
4304         }
4305         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4306                 rwi=si->sip->extra_info;
4307         }
4308         if(rwi){
4309                 proto_item *it;
4310
4311                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4312
4313                 PROTO_ITEM_SET_GENERATED(it);
4314                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4315                 PROTO_ITEM_SET_GENERATED(it);
4316         }
4317
4318         /* remaining */
4319         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4320         offset += 2;
4321
4322         BYTE_COUNT;
4323
4324         /* buffer format */
4325         CHECK_BYTE_COUNT(1);
4326         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4327         COUNT_BYTES(1);
4328
4329         /* data len */
4330         CHECK_BYTE_COUNT(2);
4331         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4332         COUNT_BYTES(2);
4333
4334         /* file data, might be DCERPC on a pipe */
4335         if (bc != 0) {
4336                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4337                     top_tree, offset, bc, bc, ofs, fid);
4338                 bc = 0;
4339         }
4340
4341         END_OF_SMB
4342
4343         return offset;
4344 }
4345
4346 static int
4347 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4348 {
4349         guint8 wc;
4350         guint16 bc, cnt;
4351         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4352         rw_info_t *rwi=NULL;
4353
4354         DISSECTOR_ASSERT(si);
4355
4356         WORD_COUNT;
4357
4358         /* write count */
4359         cnt = tvb_get_letohs(tvb, offset);
4360         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4361         offset += 2;
4362
4363         if (check_col(pinfo->cinfo, COL_INFO))
4364                 col_append_fstr(pinfo->cinfo, COL_INFO,
4365                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4366
4367         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4368                 rwi=si->sip->extra_info;
4369         }
4370         if(rwi){
4371                 proto_item *it;
4372
4373                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4374
4375                 PROTO_ITEM_SET_GENERATED(it);
4376                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4377                 PROTO_ITEM_SET_GENERATED(it);
4378         }
4379
4380         BYTE_COUNT;
4381
4382         END_OF_SMB
4383
4384         return offset;
4385 }
4386
4387 static int
4388 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4389 {
4390         guint8 wc;
4391         guint16 bc, fid;
4392
4393         WORD_COUNT;
4394
4395         /* fid */
4396         fid = tvb_get_letohs(tvb, offset);
4397         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4398         offset += 2;
4399
4400         /* lock count */
4401         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
4402         offset += 4;
4403
4404         /* offset */
4405         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4406         offset += 4;
4407
4408         BYTE_COUNT;
4409
4410         END_OF_SMB
4411
4412         return offset;
4413 }
4414
4415 static int
4416 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4417 {
4418         smb_info_t *si = pinfo->private_data;
4419         int fn_len;
4420         const char *fn;
4421         guint8 wc;
4422         guint16 bc;
4423
4424         DISSECTOR_ASSERT(si);
4425
4426         WORD_COUNT;
4427
4428         /* 2 reserved bytes */
4429         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4430         offset += 2;
4431
4432         /* Creation time */
4433         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4434
4435         BYTE_COUNT;
4436
4437         /* buffer format */
4438         CHECK_BYTE_COUNT(1);
4439         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4440         COUNT_BYTES(1);
4441
4442         /* directory name */
4443         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4444                 FALSE, FALSE, &bc);
4445         if (fn == NULL)
4446                 goto endofcommand;
4447         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4448                 fn);
4449         COUNT_BYTES(fn_len);
4450
4451         if (check_col(pinfo->cinfo, COL_INFO)) {
4452                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4453                     format_text(fn, strlen(fn)));
4454         }
4455
4456         END_OF_SMB
4457
4458         return offset;
4459 }
4460
4461 static int
4462 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4463 {
4464         smb_info_t *si = pinfo->private_data;
4465         int fn_len;
4466         const char *fn;
4467         guint8 wc;
4468         guint16 bc, fid;
4469
4470         DISSECTOR_ASSERT(si);
4471
4472         WORD_COUNT;
4473
4474         /* fid */
4475         fid = tvb_get_letohs(tvb, offset);
4476         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
4477         offset += 2;
4478
4479         BYTE_COUNT;
4480
4481         /* buffer format */
4482         CHECK_BYTE_COUNT(1);
4483         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4484         COUNT_BYTES(1);
4485
4486         /* file name */
4487         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4488                 FALSE, FALSE, &bc);
4489         if (fn == NULL)
4490                 goto endofcommand;
4491         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4492                 fn);
4493         COUNT_BYTES(fn_len);
4494
4495         END_OF_SMB
4496
4497         return offset;
4498 }
4499
4500 static const value_string seek_mode_vals[] = {
4501         {0,     "From Start Of File"},
4502         {1,     "From Current Position"},
4503         {2,     "From End Of File"},
4504         {0,     NULL}
4505 };
4506
4507 static int
4508 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4509 {
4510         guint8 wc;
4511         guint16 bc, fid;
4512
4513         WORD_COUNT;
4514
4515         /* fid */
4516         fid = tvb_get_letohs(tvb, offset);
4517         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4518         offset += 2;
4519
4520         /* Seek Mode */
4521         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
4522         offset += 2;
4523
4524         /* offset */
4525         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4526         offset += 4;
4527
4528         BYTE_COUNT;
4529
4530         END_OF_SMB
4531
4532         return offset;
4533 }
4534
4535 static int
4536 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4537 {
4538         guint8 wc;
4539         guint16 bc;
4540
4541         WORD_COUNT;
4542
4543         /* offset */
4544         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4545         offset += 4;
4546
4547         BYTE_COUNT;
4548
4549         END_OF_SMB
4550
4551         return offset;
4552 }
4553
4554 static int
4555 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4556 {
4557         guint8 wc;
4558         guint16 bc, fid;
4559
4560         WORD_COUNT;
4561
4562         /* fid */
4563         fid = tvb_get_letohs(tvb, offset);
4564         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4565         offset += 2;
4566
4567         /* create time */
4568         offset = dissect_smb_datetime(tvb, tree, offset,
4569                 hf_smb_create_time,
4570                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4571
4572         /* access time */
4573         offset = dissect_smb_datetime(tvb, tree, offset,
4574                 hf_smb_access_time,
4575                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4576
4577         /* last write time */
4578         offset = dissect_smb_datetime(tvb, tree, offset,
4579                 hf_smb_last_write_time,
4580                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4581
4582         BYTE_COUNT;
4583
4584         END_OF_SMB
4585
4586         return offset;
4587 }
4588
4589 static int
4590 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4591 {
4592         guint8 wc;
4593         guint16 bc;
4594
4595         WORD_COUNT;
4596
4597         /* create time */
4598         offset = dissect_smb_datetime(tvb, tree, offset,
4599                 hf_smb_create_time,
4600                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4601
4602         /* access time */
4603         offset = dissect_smb_datetime(tvb, tree, offset,
4604                 hf_smb_access_time,
4605                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4606
4607         /* last write time */
4608         offset = dissect_smb_datetime(tvb, tree, offset,
4609                 hf_smb_last_write_time,
4610                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4611
4612         /* data size */
4613         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
4614         offset += 4;
4615
4616         /* allocation size */
4617         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4618         offset += 4;
4619
4620         /* File Attributes */
4621         offset = dissect_file_attributes(tvb, tree, offset, 2);
4622
4623         BYTE_COUNT;
4624
4625         END_OF_SMB
4626
4627         return offset;
4628 }
4629
4630 static int
4631 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4632 {
4633         guint8 wc;
4634         guint16 cnt=0;
4635         guint16 bc, fid;
4636
4637         WORD_COUNT;
4638
4639         /* fid */
4640         fid = tvb_get_letohs(tvb, offset);
4641         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
4642         offset += 2;
4643
4644         /* write count */
4645         cnt = tvb_get_letohs(tvb, offset);
4646         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4647         offset += 2;
4648
4649         /* offset */
4650         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4651         offset += 4;
4652
4653         /* last write time */
4654         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4655
4656         if(wc==12){
4657                 /* 12 reserved bytes */
4658                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
4659                 offset += 12;
4660         }
4661
4662         BYTE_COUNT;
4663
4664         /* 1 pad byte */
4665         CHECK_BYTE_COUNT(1);
4666         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
4667         COUNT_BYTES(1);
4668
4669         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4670         bc = 0; /* XXX */
4671
4672         END_OF_SMB
4673
4674         return offset;
4675 }
4676
4677 static int
4678 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4679 {
4680         guint8 wc;
4681         guint16 bc;
4682
4683         WORD_COUNT;
4684
4685         /* write count */
4686         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4687         offset += 2;
4688
4689         BYTE_COUNT;
4690
4691         END_OF_SMB
4692
4693         return offset;
4694 }
4695
4696 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4697    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4698 */
4699 static gchar *
4700 smbext20_timeout_msecs_to_str(gint32 time)
4701 {
4702         gchar *buf;
4703 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4704
4705         if (time <= 0) {
4706                 buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4707                 if (time == 0) {
4708                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4709                 } else if (time == -1) {
4710                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4711                 } else if (time == -2) {
4712                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4713                 } else {
4714                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
4715                 }
4716                 return buf;
4717         }
4718
4719         return time_msecs_to_str(time);
4720 }
4721
4722 static int
4723 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4724 {
4725         guint8 wc;
4726         guint16 bc, fid;
4727         guint32 to;
4728
4729         WORD_COUNT;
4730
4731         /* fid */
4732         fid = tvb_get_letohs(tvb, offset);
4733         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4734         offset += 2;
4735
4736         /* offset */
4737         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4738         offset += 4;
4739
4740         /* max count */
4741         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4742         offset += 2;
4743
4744         /* min count */
4745         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4746         offset += 2;
4747
4748         /* timeout */
4749         to = tvb_get_letohl(tvb, offset);
4750         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4751         offset += 4;
4752
4753         /* 2 reserved bytes */
4754         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4755         offset += 2;
4756
4757         if(wc==10){
4758                 /* high offset */
4759                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4760                 offset += 4;
4761         }
4762
4763         BYTE_COUNT;
4764
4765         END_OF_SMB
4766
4767         return offset;
4768 }
4769
4770 static int
4771 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4772 {
4773         guint8 wc;
4774         guint16 bc;
4775
4776         WORD_COUNT;
4777
4778         /* units */
4779         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
4780         offset += 2;
4781
4782         /* bpu */
4783         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
4784         offset += 2;
4785
4786         /* block size */
4787         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4788         offset += 2;
4789
4790         /* free units */
4791         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4792         offset += 2;
4793
4794         /* 2 reserved bytes */
4795         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4796         offset += 2;
4797
4798         BYTE_COUNT;
4799
4800         END_OF_SMB
4801
4802         return offset;
4803 }
4804
4805 static int
4806 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4807 {
4808         guint8 wc;
4809         guint16 bc, fid;
4810
4811         WORD_COUNT;
4812
4813         /* fid */
4814         fid = tvb_get_letohs(tvb, offset);
4815         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4816         offset += 2;
4817
4818         /* offset */
4819         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4820         offset += 4;
4821
4822         /* max count */
4823         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4824         offset += 2;
4825
4826         /* min count */
4827         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4828         offset += 2;
4829
4830         /* 6 reserved bytes */
4831         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4832         offset += 6;
4833
4834         BYTE_COUNT;
4835
4836         END_OF_SMB
4837
4838         return offset;
4839 }
4840
4841 static int
4842 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4843 {
4844         guint16 datalen=0, bc;
4845         guint8 wc;
4846
4847         WORD_COUNT;
4848
4849         /* offset */
4850         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4851         offset += 4;
4852
4853         /* count */
4854         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4855         offset += 2;
4856
4857         /* 2 reserved bytes */
4858         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4859         offset += 2;
4860
4861         /* data compaction mode */
4862         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4863         offset += 2;
4864
4865         /* 2 reserved bytes */
4866         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4867         offset += 2;
4868
4869         /* data len */
4870         datalen = tvb_get_letohs(tvb, offset);
4871         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4872         offset += 2;
4873
4874         /* data offset */
4875         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4876         offset += 2;
4877
4878         BYTE_COUNT;
4879
4880         /* file data */
4881         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4882         bc = 0;
4883
4884         END_OF_SMB
4885
4886         return offset;
4887 }
4888
4889
4890 static const true_false_string tfs_write_mode_write_through = {
4891         "WRITE THROUGH requested",
4892         "Write through not requested"
4893 };
4894 static const true_false_string tfs_write_mode_return_remaining = {
4895         "RETURN REMAINING (pipe/dev) requested",
4896         "DON'T return remaining (pipe/dev)"
4897 };
4898 static const true_false_string tfs_write_mode_raw = {
4899         "Use WriteRawNamedPipe (pipe)",
4900         "DON'T use WriteRawNamedPipe (pipe)"
4901 };
4902 static const true_false_string tfs_write_mode_message_start = {
4903         "This is the START of a MESSAGE (pipe)",
4904         "This is NOT the start of a message (pipe)"
4905 };
4906 static const true_false_string tfs_write_mode_connectionless = {
4907         "CONNECTIONLESS mode requested",
4908         "Connectionless mode NOT requested"
4909 };
4910
4911 #define WRITE_MODE_CONNECTIONLESS       0x0080
4912 #define WRITE_MODE_MESSAGE_START        0x0008
4913 #define WRITE_MODE_RAW                  0x0004
4914 #define WRITE_MODE_RETURN_REMAINING     0x0002
4915 #define WRITE_MODE_WRITE_THROUGH        0x0001
4916
4917 static int
4918 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4919 {
4920         guint16 mask;
4921         proto_item *item;
4922         proto_tree *tree;
4923
4924         mask = tvb_get_letohs(tvb, offset);
4925
4926         if(parent_tree){
4927                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4928                         "Write Mode: 0x%04x", mask);
4929                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4930
4931                 if(bm&WRITE_MODE_CONNECTIONLESS){
4932                         proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4933                                 tvb, offset, 2, mask);
4934                 }
4935                 if(bm&WRITE_MODE_MESSAGE_START){
4936                         proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4937                                 tvb, offset, 2, mask);
4938                                 }
4939                 if(bm&WRITE_MODE_RAW){
4940                         proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4941                                 tvb, offset, 2, mask);
4942                 }
4943                 if(bm&WRITE_MODE_RETURN_REMAINING){
4944                         proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4945                                 tvb, offset, 2, mask);
4946                 }
4947                 if(bm&WRITE_MODE_WRITE_THROUGH){
4948                         proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4949                                 tvb, offset, 2, mask);
4950                 }
4951         }
4952
4953         offset += 2;
4954         return offset;
4955 }
4956
4957 static int
4958 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4959 {
4960         guint32 to;
4961         guint16 datalen=0, bc, fid;
4962         guint8 wc;
4963
4964         WORD_COUNT;
4965
4966         /* fid */
4967         fid = tvb_get_letohs(tvb, offset);
4968         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4969         offset += 2;
4970
4971         /* total data length */
4972         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4973         offset += 2;
4974
4975         /* 2 reserved bytes */
4976         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4977         offset += 2;
4978
4979         /* offset */
4980         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4981         offset += 4;
4982
4983         /* timeout */
4984         to = tvb_get_letohl(tvb, offset);
4985         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4986         offset += 4;
4987
4988         /* mode */
4989         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4990
4991         /* 4 reserved bytes */
4992         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4993         offset += 4;
4994
4995         /* data len */
4996         datalen = tvb_get_letohs(tvb, offset);
4997         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4998         offset += 2;
4999
5000         /* data offset */
5001         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
5002         offset += 2;
5003
5004         BYTE_COUNT;
5005
5006         /* file data */
5007         /* XXX - use the data offset to determine where the data starts? */
5008         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5009         bc = 0;
5010
5011         END_OF_SMB
5012
5013         return offset;
5014 }
5015
5016 static int
5017 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5018 {
5019         guint8 wc;
5020         guint16 bc;
5021
5022         WORD_COUNT;
5023
5024         /* remaining */
5025         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5026         offset += 2;
5027
5028         BYTE_COUNT;
5029
5030         END_OF_SMB
5031
5032         return offset;
5033 }
5034
5035 static int
5036 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5037 {
5038         guint32 to;
5039         guint16 datalen=0, bc, fid;
5040         guint8 wc;
5041
5042         WORD_COUNT;
5043
5044         /* fid */
5045         fid = tvb_get_letohs(tvb, offset);
5046         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5047         offset += 2;
5048
5049         /* total data length */
5050         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
5051         offset += 2;
5052
5053         /* 2 reserved bytes */
5054         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5055         offset += 2;
5056
5057         /* offset */
5058         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5059         offset += 4;
5060
5061         /* timeout */
5062         to = tvb_get_letohl(tvb, offset);
5063         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5064         offset += 4;
5065
5066         /* mode */
5067         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5068
5069         /* request mask */
5070         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
5071         offset += 4;
5072
5073         /* data len */
5074         datalen = tvb_get_letohs(tvb, offset);
5075         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5076         offset += 2;
5077
5078         /* data offset */
5079         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
5080         offset += 2;
5081
5082         BYTE_COUNT;
5083
5084         /* file data */
5085         /* XXX - use the data offset to determine where the data starts? */
5086         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5087         bc = 0;
5088
5089         END_OF_SMB
5090
5091         return offset;
5092 }
5093
5094 static int
5095 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5096 {
5097         guint8 wc;
5098         guint16 bc;
5099
5100         WORD_COUNT;
5101
5102         /* response mask */
5103         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
5104         offset += 4;
5105
5106         BYTE_COUNT;
5107
5108         END_OF_SMB
5109
5110         return offset;
5111 }
5112
5113 static int
5114 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5115 {
5116         guint8 wc;
5117         guint16 bc;
5118
5119         WORD_COUNT;
5120
5121         /* sid */
5122         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
5123         offset += 2;
5124
5125         BYTE_COUNT;
5126
5127         END_OF_SMB
5128
5129         return offset;
5130 }
5131
5132 static int
5133 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
5134     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5135     gboolean has_find_id)
5136 {
5137         proto_item *item = NULL;
5138         proto_tree *tree = NULL;
5139         smb_info_t *si = pinfo->private_data;
5140         int fn_len;
5141         const char *fn;
5142         char fname[11+1];
5143
5144         DISSECTOR_ASSERT(si);
5145
5146         if(parent_tree){
5147                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5148                         "Resume Key");
5149                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5150         }
5151
5152         /* reserved byte */
5153         CHECK_BYTE_COUNT_SUBR(1);
5154         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5155         COUNT_BYTES_SUBR(1);
5156
5157         /* file name */
5158         fn_len = 11;
5159         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5160                 TRUE, TRUE, bcp);
5161         CHECK_STRING_SUBR(fn);
5162         /* ensure that it's null-terminated */
5163         g_strlcpy(fname, fn, 11+1);
5164         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5165                 fname);
5166         COUNT_BYTES_SUBR(fn_len);
5167
5168         if (has_find_id) {
5169                 CHECK_BYTE_COUNT_SUBR(1);
5170                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
5171                 COUNT_BYTES_SUBR(1);
5172
5173                 /* server cookie */
5174                 CHECK_BYTE_COUNT_SUBR(4);
5175                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
5176                 COUNT_BYTES_SUBR(4);
5177         } else {
5178                 /* server cookie */
5179                 CHECK_BYTE_COUNT_SUBR(5);
5180                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
5181                 COUNT_BYTES_SUBR(5);
5182         }
5183
5184         /* client cookie */
5185         CHECK_BYTE_COUNT_SUBR(4);
5186         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
5187         COUNT_BYTES_SUBR(4);
5188
5189         *trunc = FALSE;
5190         return offset;
5191 }
5192
5193 static int
5194 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5195     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5196     gboolean has_find_id)
5197 {
5198         proto_item *item = NULL;
5199         proto_tree *tree = NULL;
5200         smb_info_t *si = pinfo->private_data;
5201         int fn_len;
5202         const char *fn;
5203         char fname[13+1];
5204
5205         DISSECTOR_ASSERT(si);
5206
5207         if(parent_tree){
5208                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5209                         "Directory Information");
5210                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5211         }
5212
5213         /* resume key */
5214         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5215             trunc, has_find_id);
5216         if (*trunc)
5217                 return offset;
5218
5219         /* File Attributes */
5220         CHECK_BYTE_COUNT_SUBR(1);
5221         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5222         *bcp -= 1;
5223
5224         /* last write time */
5225         CHECK_BYTE_COUNT_SUBR(4);
5226         offset = dissect_smb_datetime(tvb, tree, offset,
5227                 hf_smb_last_write_time,
5228                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5229                 TRUE);
5230         *bcp -= 4;
5231
5232         /* File Size */
5233         CHECK_BYTE_COUNT_SUBR(4);
5234         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5235         COUNT_BYTES_SUBR(4);
5236
5237         /* file name */
5238         fn_len = 13;
5239         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5240                 TRUE, TRUE, bcp);
5241         CHECK_STRING_SUBR(fn);
5242         /* ensure that it's null-terminated */
5243         g_strlcpy(fname, fn, 13+1);
5244         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5245                 fname);
5246         COUNT_BYTES_SUBR(fn_len);
5247
5248         *trunc = FALSE;
5249         return offset;
5250 }
5251
5252
5253 static int
5254 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5255     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5256     gboolean has_find_id)
5257 {
5258         smb_info_t *si = pinfo->private_data;
5259         int fn_len;
5260         const char *fn;
5261         guint16 rkl;
5262         guint8 wc;
5263         guint16 bc;
5264         gboolean trunc;
5265
5266         DISSECTOR_ASSERT(si);
5267
5268         WORD_COUNT;
5269
5270         /* max count */
5271         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5272         offset += 2;
5273
5274         /* Search Attributes */
5275         offset = dissect_search_attributes(tvb, tree, offset);
5276
5277         BYTE_COUNT;
5278
5279         /* buffer format */
5280         CHECK_BYTE_COUNT(1);
5281         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5282         COUNT_BYTES(1);
5283
5284         /* file name */
5285         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5286                 TRUE, FALSE, &bc);
5287         if (fn == NULL)
5288                 goto endofcommand;
5289         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5290                 fn);
5291         COUNT_BYTES(fn_len);
5292
5293         if (check_col(pinfo->cinfo, COL_INFO)) {
5294                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5295                     format_text(fn, strlen(fn)));
5296         }
5297
5298         /* buffer format */
5299         CHECK_BYTE_COUNT(1);
5300         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5301         COUNT_BYTES(1);
5302
5303         /* resume key length */
5304         CHECK_BYTE_COUNT(2);
5305         rkl = tvb_get_letohs(tvb, offset);
5306         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5307         COUNT_BYTES(2);
5308
5309         /* resume key */
5310         if(rkl){
5311                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5312                     &bc, &trunc, has_find_id);
5313                 if (trunc)
5314                         goto endofcommand;
5315         }
5316
5317         END_OF_SMB
5318
5319         return offset;
5320 }
5321
5322 static int
5323 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5324     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5325 {
5326         return dissect_search_find_request(tvb, pinfo, tree, offset,
5327             smb_tree, FALSE);
5328 }
5329
5330 static int
5331 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5332     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5333 {
5334         return dissect_search_find_request(tvb, pinfo, tree, offset,
5335             smb_tree, TRUE);
5336 }
5337
5338 static int
5339 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5340     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5341 {
5342         return dissect_search_find_request(tvb, pinfo, tree, offset,
5343             smb_tree, TRUE);
5344 }
5345
5346 static int
5347 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5348     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5349     gboolean has_find_id)
5350 {
5351         guint16 count=0;
5352         guint8 wc;
5353         guint16 bc;
5354         gboolean trunc;
5355
5356         WORD_COUNT;
5357
5358         /* count */
5359         count = tvb_get_letohs(tvb, offset);
5360         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5361         offset += 2;
5362
5363         BYTE_COUNT;
5364
5365         /* buffer format */
5366         CHECK_BYTE_COUNT(1);
5367         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5368         COUNT_BYTES(1);
5369
5370         /* data len */
5371         CHECK_BYTE_COUNT(2);
5372         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
5373         COUNT_BYTES(2);
5374
5375         while(count--){
5376                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5377                     &bc, &trunc, has_find_id);
5378                 if (trunc)
5379                         goto endofcommand;
5380         }
5381
5382         END_OF_SMB
5383
5384         return offset;
5385 }
5386
5387 static int
5388 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5389 {
5390         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5391             FALSE);
5392 }
5393
5394 static int
5395 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5396 {
5397         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5398             TRUE);
5399 }
5400
5401 static int
5402 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5403     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5404 {
5405         guint8 wc;
5406         guint16 bc;
5407         guint16 data_len;
5408
5409         WORD_COUNT;
5410
5411         /* reserved */
5412         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5413         offset += 2;
5414
5415         BYTE_COUNT;
5416
5417         /* buffer format */
5418         CHECK_BYTE_COUNT(1);
5419         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5420         COUNT_BYTES(1);
5421
5422         /* data len */
5423         CHECK_BYTE_COUNT(2);
5424         data_len = tvb_get_ntohs(tvb, offset);
5425         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5426         COUNT_BYTES(2);
5427
5428         if (data_len != 0) {
5429                 CHECK_BYTE_COUNT(data_len);
5430                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5431                     data_len, TRUE);
5432                 COUNT_BYTES(data_len);
5433         }
5434
5435         END_OF_SMB
5436
5437         return offset;
5438 }
5439
5440 static const value_string locking_ol_vals[] = {
5441         {0,     "Client is not holding oplock on this file"},
5442         {1,     "Level 2 oplock currently held by client"},
5443         {0, NULL}
5444 };
5445
5446 static const true_false_string tfs_lock_type_large = {
5447         "Large file locking format requested",
5448         "Large file locking format not requested"
5449 };
5450 static const true_false_string tfs_lock_type_cancel = {
5451         "Cancel outstanding lock request",
5452         "Don't cancel outstanding lock request"
5453 };
5454 static const true_false_string tfs_lock_type_change = {
5455         "Change lock type",
5456         "Don't change lock type"
5457 };
5458 static const true_false_string tfs_lock_type_oplock = {
5459         "This is an oplock break notification/response",
5460         "This is not an oplock break notification/response"
5461 };
5462 static const true_false_string tfs_lock_type_shared = {
5463         "This is a shared lock",
5464         "This is an exclusive lock"
5465 };
5466 static int
5467 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5468 {
5469         guint8  wc, cmd=0xff, lt=0, ol=0;
5470         guint16 andxoffset=0, un=0, ln=0, bc, fid, num_lock=0, num_unlock=0;
5471         guint32 to;
5472         proto_item *litem = NULL;
5473         proto_tree *ltree = NULL;
5474         proto_item *it = NULL;
5475         proto_tree *tr = NULL;
5476         int old_offset = offset;
5477         smb_info_t *si = pinfo->private_data;
5478         smb_locking_saved_info_t *ld=NULL;
5479
5480
5481         DISSECTOR_ASSERT(si);
5482
5483         WORD_COUNT;
5484
5485         /* next smb command */
5486         cmd = tvb_get_guint8(tvb, offset);
5487         if(cmd!=0xff){
5488                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5489         } else {
5490                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5491         }
5492         offset += 1;
5493
5494         /* reserved byte */
5495         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5496         offset += 1;
5497
5498         /* andxoffset */
5499         andxoffset = tvb_get_letohs(tvb, offset);
5500         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5501         offset += 2;
5502
5503         /* fid */
5504         fid = tvb_get_letohs(tvb, offset);
5505         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5506         offset += 2;
5507
5508         /* lock type */
5509         lt = tvb_get_guint8(tvb, offset);
5510         if(tree){
5511                 litem = proto_tree_add_text(tree, tvb, offset, 1,
5512                         "Lock Type: 0x%02x", lt);
5513                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5514
5515                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5516                         tvb, offset, 1, lt);
5517                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5518                         tvb, offset, 1, lt);
5519                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5520                         tvb, offset, 1, lt);
5521                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5522                         tvb, offset, 1, lt);
5523                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5524                         tvb, offset, 1, lt);
5525         }
5526         offset += 1;
5527
5528         /* oplock level */
5529         ol = tvb_get_guint8(tvb, offset);
5530         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
5531         offset += 1;
5532
5533         /* timeout */
5534         to = tvb_get_letohl(tvb, offset);
5535         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5536         offset += 4;
5537
5538         /* number of unlocks */
5539         un = tvb_get_letohs(tvb, offset);
5540         num_unlock=un;
5541         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5542         offset += 2;
5543
5544         /* number of locks */
5545         ln = tvb_get_letohs(tvb, offset);
5546         num_lock=ln;
5547         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5548         offset += 2;
5549
5550         BYTE_COUNT;
5551
5552         /* store the locking data for the response */
5553         if((!pinfo->fd->flags.visited) && si->sip){
5554                 ld=se_alloc(sizeof(smb_locking_saved_info_t));
5555                 ld->type=lt;
5556                 ld->oplock_level= ol;
5557                 ld->num_lock=num_lock;
5558                 ld->num_unlock=num_unlock;
5559                 ld->locks=NULL;
5560                 ld->unlocks=NULL;
5561                 si->sip->extra_info_type=SMB_EI_LOCKDATA;
5562                 si->sip->extra_info=ld;
5563         }
5564
5565         /* unlocks */
5566         if(un){
5567                 old_offset = offset;
5568
5569                 it = proto_tree_add_text(tree, tvb, offset, -1,
5570                         "Unlocks");
5571                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5572                 while(un--){
5573                         proto_item *litem = NULL;
5574                         proto_tree *ltree = NULL;
5575                         if(lt&0x10){
5576                                 guint64 val;
5577                                 guint16 lock_pid;
5578                                 guint64 lock_offset;
5579                                 guint64 lock_length;
5580
5581                                 /* large lock format */
5582                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5583                                         "Unlock");
5584                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5585
5586                                 /* PID */
5587                                 CHECK_BYTE_COUNT(2);
5588                                 lock_pid=tvb_get_letohs(tvb, offset);
5589                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5590                                 COUNT_BYTES(2);
5591
5592                                 /* 2 reserved bytes */
5593                                 CHECK_BYTE_COUNT(2);
5594                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5595                                 COUNT_BYTES(2);
5596
5597                                 /* offset */
5598                                 CHECK_BYTE_COUNT(8);
5599                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5600                                     | tvb_get_letohl(tvb, offset+4);
5601                                 lock_offset=val;
5602                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5603                                 COUNT_BYTES(8);
5604
5605                                 /* length */
5606                                 CHECK_BYTE_COUNT(8);
5607                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5608                                     | tvb_get_letohl(tvb, offset+4);
5609                                 lock_length=val;
5610                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5611                                 COUNT_BYTES(8);
5612
5613                                 /* remember the unlock for the reply */
5614                                 if(ld){
5615                                         smb_lock_info_t *li;
5616                                         li=se_alloc(sizeof(smb_lock_info_t));
5617                                         li->next=ld->unlocks;
5618                                         ld->unlocks=li;
5619                                         li->pid=lock_pid;
5620                                         li->offset=lock_offset;
5621                                         li->length=lock_length;
5622                                 }
5623                         } else {
5624                                 /* normal lock format */
5625                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5626                                         "Unlock");
5627                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5628
5629                                 /* PID */
5630                                 CHECK_BYTE_COUNT(2);
5631                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5632                                 COUNT_BYTES(2);
5633
5634                                 /* offset */
5635                                 CHECK_BYTE_COUNT(4);
5636                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5637                                 COUNT_BYTES(4);
5638
5639                                 /* lock count */
5640                                 CHECK_BYTE_COUNT(4);
5641                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5642                                 COUNT_BYTES(4);
5643                         }
5644                 }
5645                 proto_item_set_len(it, offset-old_offset);
5646                 it = NULL;
5647         }
5648
5649         /* locks */
5650         if(ln){
5651                 old_offset = offset;
5652
5653                 it = proto_tree_add_text(tree, tvb, offset, -1,
5654                         "Locks");
5655                 tr = proto_item_add_subtree(it, ett_smb_locks);
5656                 while(ln--){
5657                         proto_item *litem = NULL;
5658                         proto_tree *ltree = NULL;
5659                         if(lt&0x10){
5660                                 guint64 val;
5661                                 guint16 lock_pid;
5662                                 guint64 lock_offset;
5663                                 guint64 lock_length;
5664
5665                                 /* large lock format */
5666                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5667                                         "Lock");
5668                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5669
5670                                 /* PID */
5671                                 CHECK_BYTE_COUNT(2);
5672                                 lock_pid=tvb_get_letohs(tvb, offset);
5673                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5674                                 COUNT_BYTES(2);
5675
5676                                 /* 2 reserved bytes */
5677                                 CHECK_BYTE_COUNT(2);
5678                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5679                                 COUNT_BYTES(2);
5680
5681                                 /* offset */
5682                                 CHECK_BYTE_COUNT(8);
5683                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5684                                     | tvb_get_letohl(tvb, offset+4);
5685                                 lock_offset=val;
5686                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5687                                 COUNT_BYTES(8);
5688
5689                                 /* length */
5690                                 CHECK_BYTE_COUNT(8);
5691                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5692                                     | tvb_get_letohl(tvb, offset+4);
5693                                 lock_length=val;
5694                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5695                                 COUNT_BYTES(8);
5696
5697                                 /* remember the lock for the reply */
5698                                 if(ld){
5699                                         smb_lock_info_t *li;
5700                                         li=se_alloc(sizeof(smb_lock_info_t));
5701                                         li->next=ld->locks;
5702                                         ld->locks=li;
5703                                         li->pid=lock_pid;
5704                                         li->offset=lock_offset;
5705                                         li->length=lock_length;
5706                                 }
5707                         } else {
5708                                 /* normal lock format */
5709                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5710                                         "Lock");
5711                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5712
5713                                 /* PID */
5714                                 CHECK_BYTE_COUNT(2);
5715                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5716                                 COUNT_BYTES(2);
5717
5718                                 /* offset */
5719                                 CHECK_BYTE_COUNT(4);
5720                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5721                                 COUNT_BYTES(4);
5722
5723                                 /* lock count */
5724                                 CHECK_BYTE_COUNT(4);
5725                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5726                                 COUNT_BYTES(4);
5727                         }
5728                 }
5729                 proto_item_set_len(it, offset-old_offset);
5730                 it = NULL;
5731         }
5732
5733         END_OF_SMB
5734
5735         if (it != NULL) {
5736                 /*
5737                  * We ran out of byte count in the middle of dissecting
5738                  * the locks or the unlocks; set the site of the item
5739                  * we were dissecting.
5740                  */
5741                 proto_item_set_len(it, offset-old_offset);
5742         }
5743
5744         if (cmd != 0xff) {      /* there is an andX command */
5745                 if (andxoffset < offset)
5746                         THROW(ReportedBoundsError);
5747                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5748         }
5749
5750         return offset;
5751 }
5752
5753 static int
5754 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5755 {
5756         guint8  wc, cmd=0xff;
5757         guint16 andxoffset=0;
5758         guint16 bc;
5759         smb_info_t *si;
5760
5761         si = (smb_info_t *)pinfo->private_data;
5762         DISSECTOR_ASSERT(si);
5763
5764         /* print the lock info from the request */
5765         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_LOCKDATA) {
5766                 smb_locking_saved_info_t *ld;
5767                 proto_item *litem = NULL;
5768                 proto_tree *ltree = NULL;
5769
5770                 ld = si->sip->extra_info;
5771                 if (ld != NULL) {
5772                         proto_item *lit;
5773                         proto_tree *ltr;
5774                         smb_lock_info_t *li;
5775                         if(tree){
5776                                 litem = proto_tree_add_text(tree, tvb, 0, 0,
5777                                         "Lock Type: 0x%02x", ld->type);
5778                                 PROTO_ITEM_SET_GENERATED(litem);
5779                                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5780
5781                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
5782                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
5783                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
5784                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
5785                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
5786                                 proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
5787                                 proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
5788                                 proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
5789
5790                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
5791                                 ltr = proto_item_add_subtree(lit, ett_smb_lock);
5792                                 li=ld->locks;
5793                                 while(li){
5794                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5795                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5796                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5797                                         li=li->next;
5798                                 }
5799                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
5800                                 ltr = proto_item_add_subtree(lit, ett_smb_unlock);
5801                                 li=ld->unlocks;
5802                                 while(li){
5803                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5804                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5805                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5806                                         li=li->next;
5807                                 }
5808                         }
5809                 }
5810         }
5811
5812         WORD_COUNT;
5813
5814         /* next smb command */
5815         cmd = tvb_get_guint8(tvb, offset);
5816         if(cmd!=0xff){
5817                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5818         } else {
5819                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5820         }
5821         offset += 1;
5822
5823         /* reserved byte */
5824         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5825         offset += 1;
5826
5827         /* andxoffset */
5828         andxoffset = tvb_get_letohs(tvb, offset);
5829         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5830         offset += 2;
5831
5832         BYTE_COUNT;
5833
5834         END_OF_SMB
5835
5836         if (cmd != 0xff) {      /* there is an andX command */
5837                 if (andxoffset < offset)
5838                         THROW(ReportedBoundsError);
5839                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5840         }
5841
5842         return offset;
5843 }
5844
5845
5846 const value_string oa_open_vals[] = {
5847         { 0,            "No action taken?"},
5848         { 1,            "The file existed and was opened"},
5849         { 2,            "The file did not exist but was created"},
5850         { 3,            "The file existed and was truncated"},
5851         { 0x8001,       "The file existed and was opened, and an OpLock was granted"},
5852         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
5853         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
5854         {0,     NULL}
5855 };
5856 static const true_false_string tfs_oa_lock = {
5857         "File is currently opened only by this user",
5858         "File is opened by another user (or mode not supported by server)"
5859 };
5860 static int
5861 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5862 {
5863         guint16 mask;
5864         proto_item *item;
5865         proto_tree *tree;
5866
5867         mask = tvb_get_letohs(tvb, offset);
5868
5869         if(parent_tree){
5870                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5871                         "Action: 0x%04x", mask);
5872                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5873
5874                 proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5875                         tvb, offset, 2, mask);
5876                 proto_tree_add_uint(tree, hf_smb_open_action_open,
5877                         tvb, offset, 2, mask);
5878         }
5879         offset += 2;
5880
5881         return offset;
5882 }
5883
5884 static const true_false_string tfs_open_flags_add_info = {
5885         "Additional information requested",
5886         "Additional information not requested"
5887 };
5888 static const true_false_string tfs_open_flags_ex_oplock = {
5889         "Exclusive oplock requested",
5890         "Exclusive oplock not requested"
5891 };
5892 static const true_false_string tfs_open_flags_batch_oplock = {
5893         "Batch oplock requested",
5894         "Batch oplock not requested"
5895 };
5896 static const true_false_string tfs_open_flags_ealen = {
5897         "Total length of EAs requested",
5898         "Total length of EAs not requested"
5899 };
5900 static int
5901 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5902 {
5903         guint16 mask;
5904         proto_item *item;
5905         proto_tree *tree;
5906
5907         mask = tvb_get_letohs(tvb, offset);
5908
5909         if(parent_tree){
5910                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5911                         "Flags: 0x%04x", mask);
5912                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5913
5914                 if(bm&0x0001){
5915                         proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5916                                 tvb, offset, 2, mask);
5917                 }
5918                 if(bm&0x0002){
5919                         proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5920                                 tvb, offset, 2, mask);
5921                 }
5922                 if(bm&0x0004){
5923                         proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5924                                 tvb, offset, 2, mask);
5925                 }
5926                 if(bm&0x0008){
5927                         proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5928                                 tvb, offset, 2, mask);
5929                 }
5930         }
5931
5932         offset += 2;
5933
5934         return offset;
5935 }
5936
5937 static const value_string filetype_vals[] = {
5938         { 0,            "Disk file or directory"},
5939         { 1,            "Named pipe in byte mode"},
5940         { 2,            "Named pipe in message mode"},
5941         { 3,            "Spooled printer"},
5942         {0, NULL}
5943 };
5944 static int
5945 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5946 {
5947         guint8  wc, cmd=0xff;
5948         guint16 andxoffset=0, bc;
5949         guint32 to;
5950         smb_info_t *si = pinfo->private_data;
5951         int fn_len;
5952         const char *fn;
5953
5954         DISSECTOR_ASSERT(si);
5955
5956         WORD_COUNT;
5957
5958         /* next smb command */
5959         cmd = tvb_get_guint8(tvb, offset);
5960         if(cmd!=0xff){
5961                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5962         } else {
5963                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5964         }
5965         offset += 1;
5966
5967         /* reserved byte */
5968         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5969         offset += 1;
5970
5971         /* andxoffset */
5972         andxoffset = tvb_get_letohs(tvb, offset);
5973         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5974         offset += 2;
5975
5976         /* open flags */
5977         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5978
5979         /* desired access */
5980         offset = dissect_access(tvb, tree, offset, "Desired");
5981
5982         /* Search Attributes */
5983         offset = dissect_search_attributes(tvb, tree, offset);
5984
5985         /* File Attributes */
5986         offset = dissect_file_attributes(tvb, tree, offset, 2);
5987
5988         /* creation time */
5989         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5990
5991         /* open function */
5992         offset = dissect_open_function(tvb, tree, offset);
5993
5994         /* allocation size */
5995         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5996         offset += 4;
5997
5998         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
5999         to = tvb_get_letohl(tvb, offset);
6000         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
6001         offset += 4;
6002
6003         /* 4 reserved bytes */
6004         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6005         offset += 4;
6006
6007         BYTE_COUNT;
6008
6009         /* file name */
6010         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6011                 FALSE, FALSE, &bc);
6012         if (fn == NULL)
6013                 goto endofcommand;
6014         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6015                 fn);
6016         COUNT_BYTES(fn_len);
6017
6018         if (check_col(pinfo->cinfo, COL_INFO)) {
6019                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6020                     format_text(fn, strlen(fn)));
6021         }
6022
6023         END_OF_SMB
6024
6025         if (cmd != 0xff) {      /* there is an andX command */
6026                 if (andxoffset < offset)
6027                         THROW(ReportedBoundsError);
6028                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6029         }
6030
6031         return offset;
6032 }
6033
6034 static const true_false_string tfs_ipc_state_nonblocking = {
6035         "Reads/writes return immediately if no data available",
6036         "Reads/writes block if no data available"
6037 };
6038 static const value_string ipc_state_endpoint_vals[] = {
6039         { 0,            "Consumer end of pipe"},
6040         { 1,            "Server end of pipe"},
6041         {0,     NULL}
6042 };
6043 static const value_string ipc_state_pipe_type_vals[] = {
6044         { 0,            "Byte stream pipe"},
6045         { 1,            "Message pipe"},
6046         {0,     NULL}
6047 };
6048 static const value_string ipc_state_read_mode_vals[] = {
6049         { 0,            "Read pipe as a byte stream"},
6050         { 1,            "Read messages from pipe"},
6051         {0,     NULL}
6052 };
6053
6054 int
6055 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
6056     gboolean setstate)
6057 {
6058         guint16 mask;
6059         proto_item *item;
6060         proto_tree *tree;
6061
6062         mask = tvb_get_letohs(tvb, offset);
6063
6064         if(parent_tree){
6065                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6066                         "IPC State: 0x%04x", mask);
6067                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
6068
6069                 proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
6070                         tvb, offset, 2, mask);
6071                 if (!setstate) {
6072                         proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
6073                                 tvb, offset, 2, mask);
6074                         proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6075                                 tvb, offset, 2, mask);
6076                 }
6077                 proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6078                         tvb, offset, 2, mask);
6079                 if (!setstate) {
6080                         proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6081                                 tvb, offset, 2, mask);
6082                 }
6083         }
6084
6085         offset += 2;
6086
6087         return offset;
6088 }
6089
6090 static int
6091 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6092 {
6093         guint8  wc, cmd=0xff;
6094         guint16 andxoffset=0, bc;
6095         guint16 fid;
6096
6097         WORD_COUNT;
6098
6099         /* next smb command */
6100         cmd = tvb_get_guint8(tvb, offset);
6101         if(cmd!=0xff){
6102                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6103         } else {
6104                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6105         }
6106         offset += 1;
6107
6108         /* reserved byte */
6109         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6110         offset += 1;
6111
6112         /* andxoffset */
6113         andxoffset = tvb_get_letohs(tvb, offset);
6114         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6115         offset += 2;
6116
6117         /* fid */
6118         fid = tvb_get_letohs(tvb, offset);
6119         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
6120         offset += 2;
6121
6122         /* File Attributes */
6123         offset = dissect_file_attributes(tvb, tree, offset, 2);
6124
6125         /* last write time */
6126         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6127
6128         /* File Size */
6129         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
6130         offset += 4;
6131
6132         /* granted access */
6133         offset = dissect_access(tvb, tree, offset, "Granted");
6134
6135         /* File Type */
6136         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
6137         offset += 2;
6138
6139         /* IPC State */
6140         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6141
6142         /* open_action */
6143         offset = dissect_open_action(tvb, tree, offset);
6144
6145         /* server fid */
6146         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
6147         offset += 4;
6148
6149         /* 2 reserved bytes */
6150         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6151         offset += 2;
6152
6153         BYTE_COUNT;
6154
6155         END_OF_SMB
6156
6157         if (cmd != 0xff) {      /* there is an andX command */
6158                 if (andxoffset < offset)
6159                         THROW(ReportedBoundsError);
6160                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6161         }
6162
6163         return offset;
6164 }
6165
6166 static int
6167 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6168 {
6169         guint8  wc, cmd=0xff;
6170         guint16 andxoffset=0, bc, maxcnt_low;
6171         guint32 maxcnt_high;
6172         guint32 maxcnt=0;
6173         guint32 ofs = 0;
6174         smb_info_t *si= (smb_info_t *)pinfo->private_data;
6175         unsigned int fid;
6176         rw_info_t *rwi=NULL;
6177
6178
6179         DISSECTOR_ASSERT(si);
6180
6181         WORD_COUNT;
6182
6183         /* next smb command */
6184         cmd = tvb_get_guint8(tvb, offset);
6185         if(cmd!=0xff){
6186                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6187         } else {
6188                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6189         }
6190         offset += 1;
6191
6192         /* reserved byte */
6193         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6194         offset += 1;
6195
6196         /* andxoffset */
6197         andxoffset = tvb_get_letohs(tvb, offset);
6198         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6199         offset += 2;
6200
6201         /* fid */
6202         fid = tvb_get_letohs(tvb, offset);
6203         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6204         offset += 2;
6205
6206         /* offset */
6207         ofs = tvb_get_letohl(tvb, offset);
6208         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6209         offset += 4;
6210
6211         /* max count low */
6212         maxcnt_low = tvb_get_letohs(tvb, offset);
6213         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6214         offset += 2;
6215
6216         /* min count */
6217         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
6218         offset += 2;
6219
6220         /*
6221          * max count high
6222          *
6223          * XXX - we should really only do this in case we have seen
6224          * LARGE FILE being negotiated.  Unfortunately, we might not
6225          * have seen the negotiation phase in the capture....
6226          *
6227          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6228          * it's 32 bits, but the description says "High 16 bits of
6229          * MaxCount if CAP_LARGE_READX".
6230          *
6231          * The SMB File Sharing Protocol Extensions Version 2.0,
6232          * Document Version 3.3 spec doesn't speak of an extra 16
6233          * bits in max count, but it does show a 32-bit timeout
6234          * after the min count field.
6235          *
6236          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
6237          * high count and a 16-bit reserved field.
6238          *
6239          * We fetch and display it as 32 bits.
6240          *
6241          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6242          * bytes and we just ignore it.
6243          */
6244         maxcnt_high = tvb_get_letohl(tvb, offset);
6245         if(maxcnt_high==0xffffffff){
6246                 maxcnt_high=0;
6247         } else {
6248                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6249         }
6250
6251         offset += 4;
6252
6253         maxcnt=maxcnt_high;
6254         maxcnt=(maxcnt<<16)|maxcnt_low;
6255
6256         if (check_col(pinfo->cinfo, COL_INFO))
6257                 col_append_fstr(pinfo->cinfo, COL_INFO,
6258                                 ", %u byte%s at offset %u", maxcnt,
6259                                 (maxcnt == 1) ? "" : "s", ofs);
6260
6261         /* save the offset/len for this transaction */
6262         if(si->sip && !pinfo->fd->flags.visited){
6263                 rwi=se_alloc(sizeof(rw_info_t));
6264                 rwi->offset=ofs;
6265                 rwi->len=maxcnt;
6266                 rwi->fid=fid;
6267
6268                 si->sip->extra_info_type=SMB_EI_RWINFO;
6269                 si->sip->extra_info=rwi;
6270         }
6271         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6272                 rwi=si->sip->extra_info;
6273         }
6274         if(rwi){
6275                 proto_item *it;
6276
6277                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6278
6279                 PROTO_ITEM_SET_GENERATED(it);
6280                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6281                 PROTO_ITEM_SET_GENERATED(it);
6282         }
6283
6284         /* remaining */
6285         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6286         offset += 2;
6287
6288         if(wc==12){
6289                 /* high offset */
6290                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6291                 offset += 4;
6292         }
6293
6294         BYTE_COUNT;
6295
6296         END_OF_SMB
6297
6298         if (cmd != 0xff) {      /* there is an andX command */
6299                 if (andxoffset < offset)
6300                         THROW(ReportedBoundsError);
6301                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6302         }
6303
6304         return offset;
6305 }
6306
6307 static int
6308 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6309 {
6310         guint8  wc, cmd=0xff;
6311         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
6312         guint32 datalen=0, datalen_high;
6313         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6314         int fid=0;
6315         rw_info_t *rwi=NULL;
6316
6317         DISSECTOR_ASSERT(si);
6318
6319         WORD_COUNT;
6320
6321         /* next smb command */
6322         cmd = tvb_get_guint8(tvb, offset);
6323         if(cmd!=0xff){
6324                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6325         } else {
6326                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6327         }
6328         offset += 1;
6329
6330         /* reserved byte */
6331         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6332         offset += 1;
6333
6334         /* andxoffset */
6335         andxoffset = tvb_get_letohs(tvb, offset);
6336         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6337         offset += 2;
6338
6339         /* If we have seen the request, then print which FID this refers to */
6340         /* first check if we have seen the request */
6341         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6342                 fid=GPOINTER_TO_INT(si->sip->extra_info);
6343                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
6344         }
6345
6346         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6347                 rwi=si->sip->extra_info;
6348         }
6349         if(rwi){
6350                 proto_item *it;
6351
6352                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6353
6354                 PROTO_ITEM_SET_GENERATED(it);
6355                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6356                 PROTO_ITEM_SET_GENERATED(it);
6357
6358                 /* we need the fid for the call to dcerpc below */
6359                 fid=rwi->fid;
6360         }
6361
6362         /* remaining */
6363         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6364         offset += 2;
6365
6366         /* data compaction mode */
6367         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
6368         offset += 2;
6369
6370         /* 2 reserved bytes */
6371         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6372         offset += 2;
6373
6374         /* data len low */
6375         datalen_low = tvb_get_letohs(tvb, offset);
6376         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6377         offset += 2;
6378
6379         /* data offset */
6380         dataoffset=tvb_get_letohs(tvb, offset);
6381         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6382         offset += 2;
6383
6384         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6385         /* data length high */
6386         datalen_high = tvb_get_letohl(tvb, offset);
6387         if(datalen_high==0xffffffff){
6388                 datalen_high=0;
6389         } else {
6390                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6391         }
6392         offset += 4;
6393
6394         datalen=datalen_high;
6395         datalen=(datalen<<16)|datalen_low;
6396
6397
6398         if (check_col(pinfo->cinfo, COL_INFO))
6399                 col_append_fstr(pinfo->cinfo, COL_INFO,
6400                                 ", %u byte%s", datalen,
6401                                 (datalen == 1) ? "" : "s");
6402
6403
6404         /* 6 reserved bytes */
6405         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
6406         offset += 6;
6407
6408         BYTE_COUNT;
6409
6410         /* file data, might be DCERPC on a pipe */
6411         if(bc){
6412                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6413                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6414                 bc = 0;
6415         }
6416
6417         END_OF_SMB
6418
6419         if (cmd != 0xff) {      /* there is an andX command */
6420                 if (andxoffset < offset)
6421                         THROW(ReportedBoundsError);
6422                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6423         }
6424
6425         return offset;
6426 }
6427
6428 static int
6429 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6430 {
6431         guint32 ofs=0;
6432         guint8  wc, cmd=0xff;
6433         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
6434         guint32 datalen=0;
6435         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6436         unsigned int fid=0;
6437         guint16 mode = 0;
6438         rw_info_t *rwi=NULL;
6439
6440
6441         DISSECTOR_ASSERT(si);
6442
6443         WORD_COUNT;
6444
6445         /* next smb command */
6446         cmd = tvb_get_guint8(tvb, offset);
6447         if(cmd!=0xff){
6448                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6449         } else {
6450                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6451         }
6452         offset += 1;
6453
6454         /* reserved byte */
6455         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6456         offset += 1;
6457
6458         /* andxoffset */
6459         andxoffset = tvb_get_letohs(tvb, offset);
6460         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6461         offset += 2;
6462
6463         /* fid */
6464         fid = tvb_get_letohs(tvb, offset);
6465         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6466         offset += 2;
6467
6468         /* offset */
6469         ofs = tvb_get_letohl(tvb, offset);
6470         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6471         offset += 4;
6472
6473         /* reserved */
6474         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6475         offset += 4;
6476
6477         /* mode */
6478         mode = tvb_get_letohs(tvb, offset);
6479         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6480
6481         /* remaining */
6482         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6483         offset += 2;
6484
6485         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6486         /* data length high */
6487         datalen_high = tvb_get_letohs(tvb, offset);
6488         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6489         offset += 2;
6490
6491         /* data len low */
6492         datalen_low = tvb_get_letohs(tvb, offset);
6493         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6494         offset += 2;
6495
6496         datalen=datalen_high;
6497         datalen=(datalen<<16)|datalen_low;
6498
6499         /* data offset */
6500         dataoffset=tvb_get_letohs(tvb, offset);
6501         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6502         offset += 2;
6503
6504         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
6505         if (check_col(pinfo->cinfo, COL_INFO))
6506                 col_append_fstr(pinfo->cinfo, COL_INFO,
6507                                 ", %u byte%s at offset %u", datalen,
6508                                 (datalen == 1) ? "" : "s", ofs);
6509
6510         /* save the offset/len for this transaction */
6511         if(si->sip && !pinfo->fd->flags.visited){
6512                 rwi=se_alloc(sizeof(rw_info_t));
6513                 rwi->offset=ofs;
6514                 rwi->len=datalen;
6515                 rwi->fid=fid;
6516
6517                 si->sip->extra_info_type=SMB_EI_RWINFO;
6518                 si->sip->extra_info=rwi;
6519         }
6520         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6521                 rwi=si->sip->extra_info;
6522         }
6523         if(rwi){
6524                 proto_item *it;
6525
6526                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6527
6528                 PROTO_ITEM_SET_GENERATED(it);
6529                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6530                 PROTO_ITEM_SET_GENERATED(it);
6531         }
6532
6533
6534         if(wc==14){
6535                 /* high offset */
6536                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6537                 offset += 4;
6538         }
6539
6540         BYTE_COUNT;
6541
6542         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6543            the first two bytes of the payload is the length of the data.
6544            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6545            be over the IPC$ share and thus they all transport DCERPC.
6546            (if we didnt already know that from the TreeConnect call)
6547         */
6548         if(mode&WRITE_MODE_MESSAGE_START){
6549                 if(mode&WRITE_MODE_RAW){
6550                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
6551                         offset += 2;
6552                         dataoffset += 2;
6553                         bc -= 2;
6554                         datalen -= 2;
6555                 }
6556                 if(!pinfo->fd->flags.visited){
6557                         /* In case we did not see the TreeConnect call,
6558                            store this TID here as well as a IPC TID
6559                            so we know that future Read/Writes to this
6560                            TID is (probably) DCERPC.
6561                         */
6562                         if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
6563                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6564                         }
6565                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6566                 }
6567                 if(si->sip){
6568                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
6569                 }
6570         }
6571
6572         /* file data, might be DCERPC on a pipe */
6573         if (bc != 0) {
6574                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6575                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6576                 bc = 0;
6577         }
6578
6579         END_OF_SMB
6580
6581         if (cmd != 0xff) {      /* there is an andX command */
6582                 if (andxoffset < offset)
6583                         THROW(ReportedBoundsError);
6584                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6585         }
6586
6587         return offset;
6588 }
6589
6590 static int
6591 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6592 {
6593         guint8  wc, cmd=0xff;
6594         guint16 andxoffset=0, bc, count_low, count_high;
6595         guint32 count=0;
6596         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6597         rw_info_t *rwi=NULL;
6598
6599         DISSECTOR_ASSERT(si);
6600
6601         WORD_COUNT;
6602
6603         /* next smb command */
6604         cmd = tvb_get_guint8(tvb, offset);
6605         if(cmd!=0xff){
6606                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6607         } else {
6608                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6609         }
6610         offset += 1;
6611
6612         /* reserved byte */
6613         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6614         offset += 1;
6615
6616         /* andxoffset */
6617         andxoffset = tvb_get_letohs(tvb, offset);
6618         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6619         offset += 2;
6620
6621
6622         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6623                 rwi=si->sip->extra_info;
6624         }
6625         if(rwi){
6626                 proto_item *it;
6627
6628                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6629
6630                 PROTO_ITEM_SET_GENERATED(it);
6631                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6632                 PROTO_ITEM_SET_GENERATED(it);
6633         }
6634
6635
6636         /* write count low */
6637         count_low = tvb_get_letohs(tvb, offset);
6638         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6639         offset += 2;
6640
6641         /* remaining */
6642         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6643         offset += 2;
6644
6645         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6646         /* write count high */
6647         count_high = tvb_get_letohs(tvb, offset);
6648         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6649         offset += 2;
6650
6651         count=count_high;
6652         count=(count<<16)|count_low;
6653
6654         if (check_col(pinfo->cinfo, COL_INFO))
6655                 col_append_fstr(pinfo->cinfo, COL_INFO,
6656                                 ", %u byte%s", count,
6657                                 (count == 1) ? "" : "s");
6658
6659         /* 2 reserved bytes */
6660         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6661         offset += 2;
6662
6663         BYTE_COUNT;
6664
6665         END_OF_SMB
6666
6667         if (cmd != 0xff) {      /* there is an andX command */
6668                 if (andxoffset < offset)
6669                         THROW(ReportedBoundsError);
6670                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6671         }
6672
6673         return offset;
6674 }
6675
6676
6677 static const true_false_string tfs_setup_action_guest = {
6678         "Logged in as GUEST",
6679         "Not logged in as GUEST"
6680 };
6681 static int
6682 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6683 {
6684         guint16 mask;
6685         proto_item *item;
6686         proto_tree *tree;
6687
6688         mask = tvb_get_letohs(tvb, offset);
6689
6690         if(parent_tree){
6691                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6692                         "Action: 0x%04x", mask);
6693                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
6694
6695                 proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
6696                         tvb, offset, 2, mask);
6697         }
6698         offset += 2;
6699
6700         return offset;
6701 }
6702
6703
6704 static int
6705 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6706 {
6707         guint8  wc, cmd=0xff;
6708         guint16 bc;
6709         guint16 andxoffset=0;
6710         smb_info_t *si = pinfo->private_data;
6711         int an_len;
6712         const char *an;
6713         int dn_len;
6714         const char *dn;
6715         guint16 pwlen=0;
6716         guint16 sbloblen=0, sbloblen_short;
6717         guint16 apwlen=0, upwlen=0;
6718         gboolean unicodeflag;
6719         static int ntlmssp_tap_id = 0;
6720         const ntlmssp_header_t *ntlmssph;
6721
6722         if(!ntlmssp_tap_id){
6723                 GString *error_string;
6724                 /* We dont specify any callbacks at all.
6725                  * Instead we manually fetch the tapped data after the
6726                  * security blob has been fully dissected and before
6727                  * we exit from this dissector.
6728                  */
6729                 error_string=register_tap_listener("ntlmssp", NULL, NULL,
6730                     0, NULL, NULL, NULL);
6731                 if(!error_string){
6732                         ntlmssp_tap_id=find_tap_id("ntlmssp");
6733                 }
6734         }
6735
6736         DISSECTOR_ASSERT(si);
6737
6738         WORD_COUNT;
6739
6740         /* next smb command */
6741         cmd = tvb_get_guint8(tvb, offset);
6742         if(cmd!=0xff){
6743                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6744         } else {
6745                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6746         }
6747         offset += 1;
6748
6749         /* reserved byte */
6750         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6751         offset += 1;
6752
6753         /* andxoffset */
6754         andxoffset = tvb_get_letohs(tvb, offset);
6755         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6756         offset += 2;
6757
6758         /* Maximum Buffer Size */
6759         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
6760         offset += 2;
6761
6762         /* Maximum Multiplex Count */
6763         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
6764         offset += 2;
6765
6766         /* VC Number */
6767         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
6768         offset += 2;
6769
6770         /* session key */
6771         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
6772         offset += 4;
6773
6774         switch (wc) {
6775         case 10:
6776                 /* password length, ASCII*/
6777                 pwlen = tvb_get_letohs(tvb, offset);
6778                 proto_tree_add_uint(tree, hf_smb_password_len,
6779                         tvb, offset, 2, pwlen);
6780                 offset += 2;
6781
6782                 /* 4 reserved bytes */
6783                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6784                 offset += 4;
6785
6786                 break;
6787
6788         case 12:
6789                 /* security blob length */
6790                 sbloblen = tvb_get_letohs(tvb, offset);
6791                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6792                 offset += 2;
6793
6794                 /* 4 reserved bytes */
6795                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6796                 offset += 4;
6797
6798                 /* capabilities */
6799                 dissect_negprot_capabilities(tvb, tree, offset);
6800                 offset += 4;
6801
6802                 break;
6803
6804         case 13:
6805                 /* password length, ANSI*/
6806                 apwlen = tvb_get_letohs(tvb, offset);
6807                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
6808                         tvb, offset, 2, apwlen);
6809                 offset += 2;
6810
6811                 /* password length, Unicode*/
6812                 upwlen = tvb_get_letohs(tvb, offset);
6813                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
6814                         tvb, offset, 2, upwlen);
6815                 offset += 2;
6816
6817                 /* 4 reserved bytes */
6818                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6819                 offset += 4;
6820
6821                 /* capabilities */
6822                 dissect_negprot_capabilities(tvb, tree, offset);
6823                 offset += 4;
6824
6825                 break;
6826         }
6827
6828         BYTE_COUNT;
6829
6830         if (wc==12) {
6831                 proto_item *blob_item;
6832
6833                 /* security blob */
6834                 /* If it runs past the end of the captured data, don't
6835                  * try to put all of it into the protocol tree as the
6836                  * raw security blob; we might get an exception on
6837                  * short frames and then we will not see anything at all
6838                  * of the security blob.
6839                  */
6840                 sbloblen_short = sbloblen;
6841                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
6842                         sbloblen_short=tvb_length_remaining(tvb,offset);
6843                 }
6844                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6845                                                 tvb, offset, sbloblen_short,
6846                                                 TRUE);
6847
6848                 /* As an optimization, because Windows is perverse,
6849                    we check to see if NTLMSSP is the first part of the
6850                    blob, and if so, call the NTLMSSP dissector,
6851                    otherwise we call the GSS-API dissector. This is because
6852                    Windows can request RAW NTLMSSP, but will happily handle
6853                    a client that wraps NTLMSSP in SPNEGO
6854                 */
6855
6856                 if(sbloblen){
6857                         tvbuff_t *blob_tvb;
6858                         proto_tree *blob_tree;
6859
6860                         blob_tree = proto_item_add_subtree(blob_item,
6861                                                            ett_smb_secblob);
6862                         CHECK_BYTE_COUNT(sbloblen);
6863
6864                         /*
6865                          * Set the reported length of this to the reported
6866                          * length of the blob, rather than the amount of
6867                          * data available from the blob, so that we'll
6868                          * throw the right exception if it's too short.
6869                          */
6870                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
6871                                                   sbloblen);
6872
6873                         if (si && si->ct && si->ct->raw_ntlmssp &&
6874                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6875                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6876                                          blob_tree);
6877
6878                         }
6879                         else {
6880                           call_dissector(gssapi_handle, blob_tvb,
6881                                          pinfo, blob_tree);
6882                         }
6883
6884                         /* If we have found a uid->acct_name mapping, store it */
6885                         if(!pinfo->fd->flags.visited && si->sip){
6886                                 int idx=0;
6887                                 if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
6888                                         if(ntlmssph && ntlmssph->type==3){
6889                                                 smb_uid_t *smb_uid;
6890
6891                                                 smb_uid=se_alloc(sizeof(smb_uid_t));
6892                                                 smb_uid->logged_in=-1;
6893                                                 smb_uid->logged_out=-1;
6894                                                 smb_uid->domain=se_strdup(ntlmssph->domain_name);
6895                                                 smb_uid->account=se_strdup(ntlmssph->acct_name);
6896
6897                                                 si->sip->extra_info=smb_uid;
6898                                                 si->sip->extra_info_type=SMB_EI_UID;
6899                                         }
6900                                 }
6901                         }
6902
6903                         COUNT_BYTES(sbloblen);
6904                 }
6905
6906                 /* OS
6907                  * Eventhough this field should honour the unicode flag
6908                  * some ms clients gets this wrong.
6909                  * At least XP SP1 sends this in ASCII
6910                  * even when the unicode flag is on.
6911                  * Test if the first three bytes are "Win"
6912                  * and if so just override the flag.
6913                  */
6914                 unicodeflag=si->unicode;
6915                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6916                         unicodeflag=FALSE;
6917                 }
6918                 an = get_unicode_or_ascii_string(tvb, &offset,
6919                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6920                 if (an == NULL)
6921                         goto endofcommand;
6922                 proto_tree_add_string(tree, hf_smb_os, tvb,
6923                         offset, an_len, an);
6924                 COUNT_BYTES(an_len);
6925
6926                 /* LANMAN */
6927                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6928                  * padding/null string/whatever in front of this. W2K doesn't
6929                  * appear to. I suspect that's a bug that got fixed; I also
6930                  * suspect that, in practice, nobody ever looks at that field
6931                  * because the bug didn't appear to get fixed until NT 5.0....
6932                  *
6933                  * Eventhough this field should honour the unicode flag
6934                  * some ms clients gets this wrong.
6935                  * At least XP SP1 sends this in ASCII
6936                  * even when the unicode flag is on.
6937                  * Test if the first three bytes are "Win"
6938                  * and if so just override the flag.
6939                  */
6940                 unicodeflag=si->unicode;
6941                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6942                         unicodeflag=FALSE;
6943                 }
6944                 an = get_unicode_or_ascii_string(tvb, &offset,
6945                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6946                 if (an == NULL)
6947                         goto endofcommand;
6948                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6949                         offset, an_len, an);
6950                 COUNT_BYTES(an_len);
6951
6952                 /* Primary domain */
6953                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6954                  * byte in front of this, at least if all the strings are
6955                  * ASCII and the account name is empty. Another bug?
6956                  */
6957                 dn = get_unicode_or_ascii_string(tvb, &offset,
6958                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6959                 if (dn == NULL)
6960                         goto endofcommand;
6961                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6962                         offset, dn_len, dn);
6963                 COUNT_BYTES(dn_len);
6964         } else {
6965                 switch (wc) {
6966
6967                 case 10:
6968                         if(pwlen){
6969                                 /* password, ASCII */
6970                                 CHECK_BYTE_COUNT(pwlen);
6971                                 proto_tree_add_item(tree, hf_smb_password,
6972                                         tvb, offset, pwlen, TRUE);
6973                                 COUNT_BYTES(pwlen);
6974                         }
6975
6976                         break;
6977
6978                 case 13:
6979                         if(apwlen){
6980                                 /* password, ANSI */
6981                                 CHECK_BYTE_COUNT(apwlen);
6982                                 proto_tree_add_item(tree, hf_smb_ansi_password,
6983                                         tvb, offset, apwlen, TRUE);
6984                                 COUNT_BYTES(apwlen);
6985                         }
6986
6987                         if(upwlen){
6988                                 proto_item *item;
6989
6990                                 /* password, Unicode */
6991                                 CHECK_BYTE_COUNT(upwlen);
6992                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
6993                                         tvb, offset, upwlen, TRUE);
6994
6995                                 if (upwlen > 24) {
6996                                         proto_tree *subtree;
6997
6998                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
6999
7000                                         dissect_ntlmv2_response(
7001                                                 tvb, subtree, offset, upwlen);
7002                                 }
7003
7004                                 COUNT_BYTES(upwlen);
7005                         }
7006
7007                         break;
7008                 }
7009
7010                 /* Account Name */
7011                 an = get_unicode_or_ascii_string(tvb, &offset,
7012                         si->unicode, &an_len, FALSE, FALSE, &bc);
7013                 if (an == NULL)
7014                         goto endofcommand;
7015                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
7016                         an);
7017                 COUNT_BYTES(an_len);
7018
7019                 /* Primary domain */
7020                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7021                  * byte in front of this, at least if all the strings are
7022                  * ASCII and the account name is empty. Another bug?
7023                  */
7024                 dn = get_unicode_or_ascii_string(tvb, &offset,
7025                         si->unicode, &dn_len, FALSE, FALSE, &bc);
7026                 if (dn == NULL)
7027                         goto endofcommand;
7028                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7029                         offset, dn_len, dn);
7030                 COUNT_BYTES(dn_len);
7031
7032                 if (check_col(pinfo->cinfo, COL_INFO)) {
7033                         col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
7034
7035                         if (!dn[0] && !an[0])
7036                                 col_append_str(pinfo->cinfo, COL_INFO,
7037                                                 "anonymous");
7038                         else
7039                                 col_append_fstr(pinfo->cinfo, COL_INFO,
7040                                                 "%s\\%s",
7041                                                 format_text(dn, strlen(dn)),
7042                                                 format_text(an, strlen(an)));
7043                 }
7044
7045                 /* OS */
7046                 an = get_unicode_or_ascii_string(tvb, &offset,
7047                         si->unicode, &an_len, FALSE, FALSE, &bc);
7048                 if (an == NULL)
7049                         goto endofcommand;
7050                 proto_tree_add_string(tree, hf_smb_os, tvb,
7051                         offset, an_len, an);
7052                 COUNT_BYTES(an_len);
7053
7054                 /* LANMAN */
7055                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7056                  * padding/null string/whatever in front of this. W2K doesn't
7057                  * appear to. I suspect that's a bug that got fixed; I also
7058                  * suspect that, in practice, nobody ever looks at that field
7059                  * because the bug didn't appear to get fixed until NT 5.0....
7060                  */
7061                 an = get_unicode_or_ascii_string(tvb, &offset,
7062                         si->unicode, &an_len, FALSE, FALSE, &bc);
7063                 if (an == NULL)
7064                         goto endofcommand;
7065                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7066                         offset, an_len, an);
7067                 COUNT_BYTES(an_len);
7068         }
7069
7070         END_OF_SMB
7071
7072         if (cmd != 0xff) {      /* there is an andX command */
7073                 if (andxoffset < offset)
7074                         THROW(ReportedBoundsError);
7075                 pinfo->private_data = si;
7076                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7077         }
7078
7079         return offset;
7080 }
7081
7082 static int
7083 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7084 {
7085         guint8  wc, cmd=0xff;
7086         guint16 andxoffset=0, bc;
7087         guint16 sbloblen=0;
7088         smb_info_t *si = pinfo->private_data;
7089         int an_len;
7090         const char *an;
7091
7092         DISSECTOR_ASSERT(si);
7093
7094         WORD_COUNT;
7095
7096         if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7097             si->sip->extra_info_type==SMB_EI_UID){
7098                 smb_uid_t *smb_uid;
7099
7100                 smb_uid=si->sip->extra_info;
7101                 smb_uid->logged_in=pinfo->fd->num;
7102                 se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7103         }
7104
7105         /* next smb command */
7106         cmd = tvb_get_guint8(tvb, offset);
7107         if(cmd!=0xff){
7108                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7109         } else {
7110                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7111         }
7112         offset += 1;
7113
7114         /* reserved byte */
7115         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7116         offset += 1;
7117
7118         /* andxoffset */
7119         andxoffset = tvb_get_letohs(tvb, offset);
7120         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7121         offset += 2;
7122
7123         /* flags */
7124         offset = dissect_setup_action(tvb, tree, offset);
7125
7126         if(wc==4){
7127                 /* security blob length */
7128                 sbloblen = tvb_get_letohs(tvb, offset);
7129                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7130                 offset += 2;
7131         }
7132
7133         BYTE_COUNT;
7134
7135         if(wc==4) {
7136                 proto_item *blob_item;
7137
7138                 /* security blob */
7139                 /* dont try to eat too much of we might get an exception on
7140                  * short frames and then we will not see anything at all
7141                  * of the security blob.
7142                  */
7143                 if(sbloblen>tvb_length_remaining(tvb,offset)){
7144                         sbloblen=tvb_length_remaining(tvb,offset);
7145                 }
7146                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7147                                                 tvb, offset, sbloblen, TRUE);
7148
7149                 if(sbloblen){
7150                         tvbuff_t *blob_tvb;
7151                         proto_tree *blob_tree;
7152
7153                         blob_tree = proto_item_add_subtree(blob_item,
7154                                                            ett_smb_secblob);
7155                         CHECK_BYTE_COUNT(sbloblen);
7156
7157                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
7158                                                     sbloblen);
7159
7160                         if (si && si->ct && si->ct->raw_ntlmssp &&
7161                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
7162                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7163                                          blob_tree);
7164
7165                         }
7166                         else {
7167                           call_dissector(gssapi_handle, blob_tvb, pinfo,
7168                                          blob_tree);
7169
7170                         }
7171
7172                         COUNT_BYTES(sbloblen);
7173                 }
7174         }
7175
7176         /* OS */
7177         an = get_unicode_or_ascii_string(tvb, &offset,
7178                 si->unicode, &an_len, FALSE, FALSE, &bc);
7179         if (an == NULL)
7180                 goto endofcommand;
7181         proto_tree_add_string(tree, hf_smb_os, tvb,
7182                 offset, an_len, an);
7183         COUNT_BYTES(an_len);
7184
7185         /* LANMAN */
7186         an = get_unicode_or_ascii_string(tvb, &offset,
7187                 si->unicode, &an_len, FALSE, FALSE, &bc);
7188         if (an == NULL)
7189                 goto endofcommand;
7190         proto_tree_add_string(tree, hf_smb_lanman, tvb,
7191                 offset, an_len, an);
7192         COUNT_BYTES(an_len);
7193
7194         if((wc==3)||(wc==4)) {
7195                 /* Primary domain */
7196                 an = get_unicode_or_ascii_string(tvb, &offset,
7197                         si->unicode, &an_len, FALSE, FALSE, &bc);
7198                 if (an == NULL)
7199                         goto endofcommand;
7200                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7201                         offset, an_len, an);
7202                 COUNT_BYTES(an_len);
7203         }
7204
7205         END_OF_SMB
7206
7207         if (cmd != 0xff) {      /* there is an andX command */
7208                 if (andxoffset < offset)
7209                         THROW(ReportedBoundsError);
7210                 pinfo->private_data = si;
7211                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7212         }
7213
7214         return offset;
7215 }
7216
7217
7218 static int
7219 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7220 {
7221         guint8  wc, cmd=0xff;
7222         guint16 andxoffset=0;
7223         guint16 bc;
7224
7225         WORD_COUNT;
7226
7227         /* next smb command */
7228         cmd = tvb_get_guint8(tvb, offset);
7229         if(cmd!=0xff){
7230                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7231         } else {
7232                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7233         }
7234         offset += 1;
7235
7236         /* reserved byte */
7237         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7238         offset += 1;
7239
7240         /* andxoffset */
7241         andxoffset = tvb_get_letohs(tvb, offset);
7242         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7243         offset += 2;
7244
7245         BYTE_COUNT;
7246
7247         END_OF_SMB
7248
7249         if (cmd != 0xff) {      /* there is an andX command */
7250                 if (andxoffset < offset)
7251                         THROW(ReportedBoundsError);
7252                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7253         }
7254
7255         return offset;
7256 }
7257
7258
7259 static const true_false_string tfs_connect_support_search = {
7260         "Exclusive search bits supported",
7261         "Exclusive search bits not supported"
7262 };
7263 static const true_false_string tfs_connect_support_in_dfs = {
7264         "Share is in Dfs",
7265         "Share isn't in Dfs"
7266 };
7267
7268 static int
7269 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7270 {
7271         guint16 mask;
7272         proto_item *item;
7273         proto_tree *tree;
7274
7275         mask = tvb_get_letohs(tvb, offset);
7276
7277         if(parent_tree){
7278                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7279                         "Optional Support: 0x%04x", mask);
7280                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7281
7282                 proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7283                         tvb, offset, 2, mask);
7284                 proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7285                         tvb, offset, 2, mask);
7286         }
7287
7288         offset += 2;
7289
7290         return offset;
7291 }
7292
7293 static const true_false_string tfs_disconnect_tid = {
7294         "DISCONNECT TID",
7295         "Do NOT disconnect TID"
7296 };
7297
7298 static int
7299 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7300 {
7301         guint16 mask;
7302         proto_item *item;
7303         proto_tree *tree;
7304
7305         mask = tvb_get_letohs(tvb, offset);
7306
7307         if(parent_tree){
7308                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7309                         "Flags: 0x%04x", mask);
7310                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7311
7312                 proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7313                         tvb, offset, 2, mask);
7314         }
7315
7316         offset += 2;
7317
7318         return offset;
7319 }
7320
7321 static int
7322 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7323 {
7324         guint8  wc, cmd=0xff;
7325         guint16 bc;
7326         guint16 andxoffset=0, pwlen=0;
7327         smb_info_t *si = pinfo->private_data;
7328         int an_len;
7329         const char *an;
7330
7331         DISSECTOR_ASSERT(si);
7332
7333         WORD_COUNT;
7334
7335         /* next smb command */
7336         cmd = tvb_get_guint8(tvb, offset);
7337         if(cmd!=0xff){
7338                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7339         } else {
7340                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7341         }
7342         offset += 1;
7343
7344         /* reserved byte */
7345         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7346         offset += 1;
7347
7348         /* andxoffset */
7349         andxoffset = tvb_get_letohs(tvb, offset);
7350         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7351         offset += 2;
7352
7353         /* flags */
7354         offset = dissect_connect_flags(tvb, tree, offset);
7355
7356         /* password length*/
7357         pwlen = tvb_get_letohs(tvb, offset);
7358         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7359         offset += 2;
7360
7361         BYTE_COUNT;
7362
7363         /* password */
7364         CHECK_BYTE_COUNT(pwlen);
7365         proto_tree_add_item(tree, hf_smb_password,
7366                 tvb, offset, pwlen, TRUE);
7367         COUNT_BYTES(pwlen);
7368
7369         /* Path */
7370         an = get_unicode_or_ascii_string(tvb, &offset,
7371                 si->unicode, &an_len, FALSE, FALSE, &bc);
7372         if (an == NULL)
7373                 goto endofcommand;
7374         proto_tree_add_string(tree, hf_smb_path, tvb,
7375                 offset, an_len, an);
7376         COUNT_BYTES(an_len);
7377
7378         /* store it for the tid->name/openframe/closeframe matching in
7379          * dissect_smb_tid()   called from the response.
7380          */
7381         if((!pinfo->fd->flags.visited) && si->sip && an){
7382                 si->sip->extra_info_type=SMB_EI_TIDNAME;
7383                 si->sip->extra_info=se_strdup(an);
7384         }
7385
7386         if (check_col(pinfo->cinfo, COL_INFO)) {
7387                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7388                     format_text(an, strlen(an)));
7389         }
7390
7391         /*
7392          * NOTE: the Service string is always ASCII, even if the
7393          * "strings are Unicode" bit is set in the flags2 field
7394          * of the SMB.
7395          */
7396
7397         /* Service */
7398         /* XXX - what if this runs past bc? */
7399         an_len = tvb_strsize(tvb, offset);
7400         CHECK_BYTE_COUNT(an_len);
7401         an = tvb_get_ptr(tvb, offset, an_len);
7402         proto_tree_add_string(tree, hf_smb_service, tvb,
7403                 offset, an_len, an);
7404         COUNT_BYTES(an_len);
7405
7406         END_OF_SMB
7407
7408         if (cmd != 0xff) {      /* there is an andX command */
7409                 if (andxoffset < offset)
7410                         THROW(ReportedBoundsError);
7411                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7412         }
7413
7414         return offset;
7415 }
7416
7417
7418 static int
7419 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7420 {
7421         guint8  wc, wleft, cmd=0xff;
7422         guint16 andxoffset=0;
7423         guint16 bc;
7424         int an_len;
7425         const char *an;
7426         smb_info_t *si = pinfo->private_data;
7427
7428         DISSECTOR_ASSERT(si);
7429
7430         WORD_COUNT;
7431
7432         wleft = wc;     /* this is at least 1 */
7433
7434         /* next smb command */
7435         cmd = tvb_get_guint8(tvb, offset);
7436         if(cmd!=0xff){
7437                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7438         } else {
7439                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7440         }
7441         offset += 1;
7442
7443         /* reserved byte */
7444         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7445         offset += 1;
7446
7447         wleft--;
7448         if (wleft == 0)
7449                 goto bytecount;
7450
7451         /* andxoffset */
7452         andxoffset = tvb_get_letohs(tvb, offset);
7453         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7454         offset += 2;
7455         wleft--;
7456         if (wleft == 0)
7457                 goto bytecount;
7458
7459         /* flags */
7460         offset = dissect_connect_support_bits(tvb, tree, offset);
7461         wleft--;
7462
7463         /* XXX - I've seen captures where this is 7, but I have no
7464            idea how to dissect it.  I'm guessing the third word
7465            contains connect support bits, which looks plausible
7466            from the values I've seen. */
7467
7468         while (wleft != 0) {
7469                 proto_tree_add_text(tree, tvb, offset, 2,
7470                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
7471                 offset += 2;
7472                 wleft--;
7473         }
7474
7475         BYTE_COUNT;
7476
7477         /*
7478          * NOTE: even though the SNIA CIFS spec doesn't say there's
7479          * a "Service" string if there's a word count of 2, the
7480          * document at
7481          *
7482          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7483          *
7484          * (it's in an ugly format - text intended to be sent to a
7485          * printer, with backspaces and overstrikes used for boldfacing
7486          * and underlining; UNIX "col -b" can be used to strip the
7487          * overstrikes out) says there's a "Service" string there, and
7488          * some network traffic has it.
7489          */
7490
7491         /*
7492          * NOTE: the Service string is always ASCII, even if the
7493          * "strings are Unicode" bit is set in the flags2 field
7494          * of the SMB.
7495          */
7496
7497         /* Service */
7498         /* XXX - what if this runs past bc? */
7499         an_len = tvb_strsize(tvb, offset);
7500         CHECK_BYTE_COUNT(an_len);
7501         an = tvb_get_ptr(tvb, offset, an_len);
7502         proto_tree_add_string(tree, hf_smb_service, tvb,
7503                 offset, an_len, an);
7504         COUNT_BYTES(an_len);
7505
7506         /* Now when we know the service type, store it so that we know it for later commands down
7507            this tree */
7508         if(!pinfo->fd->flags.visited){
7509                 /* Remove any previous entry for this TID */
7510                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
7511                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7512                 }
7513                 if(strcmp(an,"IPC") == 0){
7514                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7515                 } else {
7516                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7517                 }
7518         }
7519
7520
7521         if(wc==3){
7522                 if (bc != 0) {
7523                         /*
7524                          * Sometimes this isn't present.
7525                          */
7526
7527                         /* Native FS */
7528                         an = get_unicode_or_ascii_string(tvb, &offset,
7529                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7530                                 &bc);
7531                         if (an == NULL)
7532                                 goto endofcommand;
7533                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7534                                 offset, an_len, an);
7535                         COUNT_BYTES(an_len);
7536                 }
7537         }
7538
7539         END_OF_SMB
7540
7541         if (cmd != 0xff) {      /* there is an andX command */
7542                 if (andxoffset < offset)
7543                         THROW(ReportedBoundsError);
7544                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7545         }
7546
7547         return offset;
7548 }
7549
7550
7551
7552 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7553    NT Transaction command  begins here
7554    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7555 #define NT_TRANS_CREATE         1
7556 #define NT_TRANS_IOCTL          2
7557 #define NT_TRANS_SSD            3
7558 #define NT_TRANS_NOTIFY         4
7559 #define NT_TRANS_RENAME         5
7560 #define NT_TRANS_QSD            6
7561 #define NT_TRANS_GET_USER_QUOTA 7
7562 #define NT_TRANS_SET_USER_QUOTA 8
7563 const value_string nt_cmd_vals[] = {
7564         {NT_TRANS_CREATE,               "NT CREATE"},
7565         {NT_TRANS_IOCTL,                "NT IOCTL"},
7566         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7567         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7568         {NT_TRANS_RENAME,               "NT RENAME"},
7569         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7570         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7571         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7572         {0, NULL}
7573 };
7574
7575 static const value_string nt_ioctl_isfsctl_vals[] = {
7576         {0,     "Device IOCTL"},
7577         {1,     "FS control : FSCTL"},
7578         {0, NULL}
7579 };
7580
7581 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7582 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7583         "Apply the command to share root handle (MUST BE Dfs)",
7584         "Apply to this share",
7585 };
7586
7587 static const value_string nt_notify_action_vals[] = {
7588         {1,     "ADDED (object was added"},
7589         {2,     "REMOVED (object was removed)"},
7590         {3,     "MODIFIED (object was modified)"},
7591         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7592         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7593         {6,     "ADDED_STREAM (a stream was added)"},
7594         {7,     "REMOVED_STREAM (a stream was removed)"},
7595         {8,     "MODIFIED_STREAM (a stream was modified)"},
7596         {0, NULL}
7597 };
7598
7599 static const value_string watch_tree_vals[] = {
7600         {0,     "Current directory only"},
7601         {1,     "Subdirectories also"},
7602         {0, NULL}
7603 };
7604
7605 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7606 #define NT_NOTIFY_STREAM_SIZE   0x00000400
7607 #define NT_NOTIFY_STREAM_NAME   0x00000200
7608 #define NT_NOTIFY_SECURITY      0x00000100
7609 #define NT_NOTIFY_EA            0x00000080
7610 #define NT_NOTIFY_CREATION      0x00000040
7611 #define NT_NOTIFY_LAST_ACCESS   0x00000020
7612 #define NT_NOTIFY_LAST_WRITE    0x00000010
7613 #define NT_NOTIFY_SIZE          0x00000008
7614 #define NT_NOTIFY_ATTRIBUTES    0x00000004
7615 #define NT_NOTIFY_DIR_NAME      0x00000002
7616 #define NT_NOTIFY_FILE_NAME     0x00000001
7617 static const true_false_string tfs_nt_notify_stream_write = {
7618         "Notify on changes to STREAM WRITE",
7619         "Do NOT notify on changes to stream write",
7620 };
7621 static const true_false_string tfs_nt_notify_stream_size = {
7622         "Notify on changes to STREAM SIZE",
7623         "Do NOT notify on changes to stream size",
7624 };
7625 static const true_false_string tfs_nt_notify_stream_name = {
7626         "Notify on changes to STREAM NAME",
7627         "Do NOT notify on changes to stream name",
7628 };
7629 static const true_false_string tfs_nt_notify_security = {
7630         "Notify on changes to SECURITY",
7631         "Do NOT notify on changes to security",
7632 };
7633 static const true_false_string tfs_nt_notify_ea = {
7634         "Notify on changes to EA",
7635         "Do NOT notify on changes to EA",
7636 };
7637 static const true_false_string tfs_nt_notify_creation = {
7638         "Notify on changes to CREATION TIME",
7639         "Do NOT notify on changes to creation time",
7640 };
7641 static const true_false_string tfs_nt_notify_last_access = {
7642         "Notify on changes to LAST ACCESS TIME",
7643         "Do NOT notify on changes to last access time",
7644 };
7645 static const true_false_string tfs_nt_notify_last_write = {
7646         "Notify on changes to LAST WRITE TIME",
7647         "Do NOT notify on changes to last write time",
7648 };
7649 static const true_false_string tfs_nt_notify_size = {
7650         "Notify on changes to SIZE",
7651         "Do NOT notify on changes to size",
7652 };
7653 static const true_false_string tfs_nt_notify_attributes = {
7654         "Notify on changes to ATTRIBUTES",
7655         "Do NOT notify on changes to attributes",
7656 };
7657 static const true_false_string tfs_nt_notify_dir_name = {
7658         "Notify on changes to DIR NAME",
7659         "Do NOT notify on changes to dir name",
7660 };
7661 static const true_false_string tfs_nt_notify_file_name = {
7662         "Notify on changes to FILE NAME",
7663         "Do NOT notify on changes to file name",
7664 };
7665
7666 const value_string create_disposition_vals[] = {
7667         {0,     "Supersede (supersede existing file (if it exists))"},
7668         {1,     "Open (if file exists open it, else fail)"},
7669         {2,     "Create (if file exists fail, else create it)"},
7670         {3,     "Open If (if file exists open it, else create it)"},
7671         {4,     "Overwrite (if file exists overwrite, else fail)"},
7672         {5,     "Overwrite If (if file exists overwrite, else create it)"},
7673         {0, NULL}
7674 };
7675
7676 const value_string impersonation_level_vals[] = {
7677         {0,     "Anonymous"},
7678         {1,     "Identification"},
7679         {2,     "Impersonation"},
7680         {3,     "Delegation"},
7681         {0, NULL}
7682 };
7683
7684 static const true_false_string tfs_nt_security_flags_context_tracking = {
7685         "Security tracking mode is DYNAMIC",
7686         "Security tracking mode is STATIC",
7687 };
7688
7689 static const true_false_string tfs_nt_security_flags_effective_only = {
7690         "ONLY ENABLED aspects of the client's security context are available",
7691         "ALL aspects of the client's security context are available",
7692 };
7693
7694 static const true_false_string tfs_nt_create_bits_oplock = {
7695         "Requesting OPLOCK",
7696         "Does NOT request oplock"
7697 };
7698
7699 static const true_false_string tfs_nt_create_bits_boplock = {
7700         "Requesting BATCH OPLOCK",
7701         "Does NOT request batch oplock"
7702 };
7703
7704 /*
7705  * XXX - must be a directory, and can be a file, or can be a directory,
7706  * and must be a file?
7707  */
7708 static const true_false_string tfs_nt_create_bits_dir = {
7709         "Target of open MUST be a DIRECTORY",
7710         "Target of open can be a file"
7711 };
7712
7713 static const true_false_string tfs_nt_create_bits_ext_resp = {
7714   "Extended responses required",
7715   "Extended responses NOT required"
7716 };
7717
7718 static const true_false_string tfs_nt_access_mask_generic_read = {
7719         "GENERIC READ is set",
7720         "Generic read is NOT set"
7721 };
7722 static const true_false_string tfs_nt_access_mask_generic_write = {
7723         "GENERIC WRITE is set",
7724         "Generic write is NOT set"
7725 };
7726 static const true_false_string tfs_nt_access_mask_generic_execute = {
7727         "GENERIC EXECUTE is set",
7728         "Generic execute is NOT set"
7729 };
7730 static const true_false_string tfs_nt_access_mask_generic_all = {
7731         "GENERIC ALL is set",
7732         "Generic all is NOT set"
7733 };
7734 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
7735         "MAXIMUM ALLOWED is set",
7736         "Maximum allowed is NOT set"
7737 };
7738 static const true_false_string tfs_nt_access_mask_system_security = {
7739         "SYSTEM SECURITY is set",
7740         "System security is NOT set"
7741 };
7742 static const true_false_string tfs_nt_access_mask_synchronize = {
7743         "Can wait on handle to SYNCHRONIZE on completion of I/O",
7744         "Can NOT wait on handle to synchronize on completion of I/O"
7745 };
7746 static const true_false_string tfs_nt_access_mask_write_owner = {
7747         "Can WRITE OWNER (take ownership)",
7748         "Can NOT write owner (take ownership)"
7749 };
7750 static const true_false_string tfs_nt_access_mask_write_dac = {
7751         "OWNER may WRITE the DAC",
7752         "Owner may NOT write to the DAC"
7753 };
7754 static const true_false_string tfs_nt_access_mask_read_control = {
7755         "READ ACCESS to owner, group and ACL of the SID",
7756         "Read access is NOT granted to owner, group and ACL of the SID"
7757 };
7758 static const true_false_string tfs_nt_access_mask_delete = {
7759         "DELETE access",
7760         "NO delete access"
7761 };
7762 static const true_false_string tfs_nt_access_mask_write_attributes = {
7763         "WRITE ATTRIBUTES access",
7764         "NO write attributes access"
7765 };
7766 static const true_false_string tfs_nt_access_mask_read_attributes = {
7767         "READ ATTRIBUTES access",
7768         "NO read attributes access"
7769 };
7770 static const true_false_string tfs_nt_access_mask_delete_child = {
7771         "DELETE CHILD access",
7772         "NO delete child access"
7773 };
7774 static const true_false_string tfs_nt_access_mask_execute = {
7775         "EXECUTE access",
7776         "NO execute access"
7777 };
7778 static const true_false_string tfs_nt_access_mask_write_ea = {
7779         "WRITE EXTENDED ATTRIBUTES access",
7780         "NO write extended attributes access"
7781 };
7782 static const true_false_string tfs_nt_access_mask_read_ea = {
7783         "READ EXTENDED ATTRIBUTES access",
7784         "NO read extended attributes access"
7785 };
7786 static const true_false_string tfs_nt_access_mask_append = {
7787         "APPEND access",
7788         "NO append access"
7789 };
7790 static const true_false_string tfs_nt_access_mask_write = {
7791         "WRITE access",
7792         "NO write access"
7793 };
7794 static const true_false_string tfs_nt_access_mask_read = {
7795         "READ access",
7796         "NO read access"
7797 };
7798
7799 static const true_false_string tfs_nt_share_access_delete = {
7800         "Object can be shared for DELETE",
7801         "Object can NOT be shared for delete"
7802 };
7803 static const true_false_string tfs_nt_share_access_write = {
7804         "Object can be shared for WRITE",
7805         "Object can NOT be shared for write"
7806 };
7807 static const true_false_string tfs_nt_share_access_read = {
7808         "Object can be shared for READ",
7809         "Object can NOT be shared for read"
7810 };
7811
7812 static const value_string oplock_level_vals[] = {
7813         {0,     "No oplock granted"},
7814         {1,     "Exclusive oplock granted"},
7815         {2,     "Batch oplock granted"},
7816         {3,     "Level II oplock granted"},
7817         {0, NULL}
7818 };
7819
7820 static const value_string device_type_vals[] = {
7821         {0x00000001,    "Beep"},
7822         {0x00000002,    "CDROM"},
7823         {0x00000003,    "CDROM Filesystem"},
7824         {0x00000004,    "Controller"},
7825         {0x00000005,    "Datalink"},
7826         {0x00000006,    "Dfs"},
7827         {0x00000007,    "Disk"},
7828         {0x00000008,    "Disk Filesystem"},
7829         {0x00000009,    "Filesystem"},
7830         {0x0000000a,    "Inport Port"},
7831         {0x0000000b,    "Keyboard"},
7832         {0x0000000c,    "Mailslot"},
7833         {0x0000000d,    "MIDI-In"},
7834         {0x0000000e,    "MIDI-Out"},
7835         {0x0000000f,    "Mouse"},
7836         {0x00000010,    "Multi UNC Provider"},
7837         {0x00000011,    "Named Pipe"},
7838         {0x00000012,    "Network"},
7839         {0x00000013,    "Network Browser"},
7840         {0x00000014,    "Network Filesystem"},
7841         {0x00000015,    "NULL"},
7842         {0x00000016,    "Parallel Port"},
7843         {0x00000017,    "Physical card"},
7844         {0x00000018,    "Printer"},
7845         {0x00000019,    "Scanner"},
7846         {0x0000001a,    "Serial Mouse port"},
7847         {0x0000001b,    "Serial port"},
7848         {0x0000001c,    "Screen"},
7849         {0x0000001d,    "Sound"},
7850         {0x0000001e,    "Streams"},
7851         {0x0000001f,    "Tape"},
7852         {0x00000020,    "Tape Filesystem"},
7853         {0x00000021,    "Transport"},
7854         {0x00000022,    "Unknown"},
7855         {0x00000023,    "Video"},
7856         {0x00000024,    "Virtual Disk"},
7857         {0x00000025,    "WAVE-In"},
7858         {0x00000026,    "WAVE-Out"},
7859         {0x00000027,    "8042 Port"},
7860         {0x00000028,    "Network Redirector"},
7861         {0x00000029,    "Battery"},
7862         {0x0000002a,    "Bus Extender"},
7863         {0x0000002b,    "Modem"},
7864         {0x0000002c,    "VDM"},
7865         {0,     NULL}
7866 };
7867
7868 static const value_string is_directory_vals[] = {
7869         {0,     "This is NOT a directory"},
7870         {1,     "This is a DIRECTORY"},
7871         {0, NULL}
7872 };
7873
7874 typedef struct _nt_trans_data {
7875         int subcmd;
7876         guint32 sd_len;
7877         guint32 ea_len;
7878 } nt_trans_data;
7879
7880
7881
7882 static int
7883 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7884 {
7885         guint8 mask;
7886         proto_item *item;
7887         proto_tree *tree;
7888
7889         mask = tvb_get_guint8(tvb, offset);
7890
7891         if(parent_tree){
7892                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7893                         "Security Flags: 0x%02x", mask);
7894                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
7895
7896                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
7897                         tvb, offset, 1, mask);
7898                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
7899                         tvb, offset, 1, mask);
7900         }
7901
7902         offset += 1;
7903
7904         return offset;
7905 }
7906
7907 /*
7908  * XXX - there are some more flags in the description of "ZwOpenFile()"
7909  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7910  * the wire as well?  (The spec at
7911  *
7912  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7913  *
7914  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7915  * via the SMB protocol.  The NT redirector should convert this option
7916  * to FILE_WRITE_THROUGH."
7917  *
7918  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7919  * values one would infer from their position in the list of flags for
7920  * "ZwOpenFile()".  Most of the others probably have those values
7921  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7922  * which might go over the wire (for the benefit of backup/restore software).
7923  */
7924 static const true_false_string tfs_nt_create_options_directory = {
7925         "File being created/opened must be a directory",
7926         "File being created/opened must not be a directory"
7927 };
7928 static const true_false_string tfs_nt_create_options_write_through = {
7929         "Writes should flush buffered data before completing",
7930         "Writes need not flush buffered data before completing"
7931 };
7932 static const true_false_string tfs_nt_create_options_sequential_only = {
7933         "The file will only be accessed sequentially",
7934         "The file might not only be accessed sequentially"
7935 };
7936 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
7937         "NO intermediate buffering is allowed",
7938         "Intermediate buffering is allowed"
7939 };
7940 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7941         "All operations SYNCHRONOUS, waits subject to termination from alert",
7942         "Operations NOT necessarily synchronous"
7943 };
7944 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7945         "All operations SYNCHRONOUS, waits not subject to alert",
7946         "Operations NOT necessarily synchronous"
7947 };
7948 static const true_false_string tfs_nt_create_options_non_directory = {
7949         "File being created/opened must not be a directory",
7950         "File being created/opened must be a directory"
7951 };
7952 static const true_false_string tfs_nt_create_options_create_tree_connection = {
7953         "Create Tree Connections is SET",
7954         "Create Tree Connections is NOT set"
7955 };
7956 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
7957         "Complete if oplocked is SET",
7958         "Complete if oplocked is NOT set"
7959 };
7960 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7961         "The client does not understand extended attributes",
7962         "The client understands extended attributes"
7963 };
7964 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7965         "The client understands only 8.3 file names",
7966         "The client understands long file names"
7967 };
7968 static const true_false_string tfs_nt_create_options_random_access = {
7969         "The file will be accessed randomly",
7970         "The file will not be accessed randomly"
7971 };
7972 static const true_false_string tfs_nt_create_options_delete_on_close = {
7973         "The file should be deleted when it is closed",
7974         "The file should not be deleted when it is closed"
7975 };
7976 static const true_false_string tfs_nt_create_options_open_by_fileid = {
7977         "OpenByFileID bit is SET",
7978         "OpenByFileID is NOT set"
7979 };
7980 static const true_false_string tfs_nt_create_options_backup_intent = {
7981         "This is a create with BACKUP INTENT",
7982         "This is a normal create"
7983 };
7984 static const true_false_string tfs_nt_create_options_no_compression = {
7985         "Open/Create with NO Compression",
7986         "Compression is allowed for Open/Create"
7987 };
7988 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
7989         "Reserve Opfilter is SET",
7990         "Reserve Opfilter is NOT set"
7991 };
7992 static const true_false_string tfs_nt_create_options_open_reparse_point = {
7993         "Open a Reparse Point",
7994         "Normal open"
7995 };
7996 static const true_false_string tfs_nt_create_options_open_no_recall = {
7997         "Open No Recall is SET",
7998         "Open no recall is NOT set"
7999 };
8000 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
8001         "This is an OPEN FOR FREE SPACE QUERY",
8002         "This is NOT an open for free space query"
8003 };
8004
8005 int
8006 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8007 {
8008         guint32 mask;
8009         proto_item *item;
8010         proto_tree *tree;
8011
8012         mask = tvb_get_letohl(tvb, offset);
8013
8014         if(parent_tree){
8015                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8016                         "Completion Filter: 0x%08x", mask);
8017                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
8018
8019                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
8020                         tvb, offset, 4, mask);
8021                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
8022                         tvb, offset, 4, mask);
8023                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
8024                         tvb, offset, 4, mask);
8025                 proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
8026                         tvb, offset, 4, mask);
8027                 proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
8028                         tvb, offset, 4, mask);
8029                 proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
8030                         tvb, offset, 4, mask);
8031                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
8032                         tvb, offset, 4, mask);
8033                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
8034                         tvb, offset, 4, mask);
8035                 proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
8036                         tvb, offset, 4, mask);
8037                 proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
8038                         tvb, offset, 4, mask);
8039                 proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
8040                         tvb, offset, 4, mask);
8041                 proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
8042                         tvb, offset, 4, mask);
8043         }
8044
8045         offset += 4;
8046         return offset;
8047 }
8048
8049 static int
8050 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8051 {
8052         guint8 mask;
8053         proto_item *item;
8054         proto_tree *tree;
8055
8056         mask = tvb_get_guint8(tvb, offset);
8057
8058         if(parent_tree){
8059                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
8060                         "Completion Filter: 0x%02x", mask);
8061                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
8062
8063                 proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
8064                         tvb, offset, 1, mask);
8065         }
8066
8067         offset += 1;
8068         return offset;
8069 }
8070
8071 /*
8072  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8073  * Native API Reference".
8074  */
8075 static const true_false_string tfs_nt_qsd_owner = {
8076         "Requesting OWNER security information",
8077         "NOT requesting owner security information",
8078 };
8079
8080 static const true_false_string tfs_nt_qsd_group = {
8081         "Requesting GROUP security information",
8082         "NOT requesting group security information",
8083 };
8084
8085 static const true_false_string tfs_nt_qsd_dacl = {
8086         "Requesting DACL security information",
8087         "NOT requesting DACL security information",
8088 };
8089
8090 static const true_false_string tfs_nt_qsd_sacl = {
8091         "Requesting SACL security information",
8092         "NOT requesting SACL security information",
8093 };
8094
8095 #define NT_QSD_OWNER    0x00000001
8096 #define NT_QSD_GROUP    0x00000002
8097 #define NT_QSD_DACL     0x00000004
8098 #define NT_QSD_SACL     0x00000008
8099
8100 int
8101 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8102 {
8103         guint32 mask;
8104         proto_item *item;
8105         proto_tree *tree;
8106
8107         mask = tvb_get_letohl(tvb, offset);
8108
8109         if(parent_tree){
8110                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8111                         "Security Information: 0x%08x", mask);
8112                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8113
8114                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8115                         tvb, offset, 4, mask);
8116                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8117                         tvb, offset, 4, mask);
8118                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8119                         tvb, offset, 4, mask);
8120                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8121                         tvb, offset, 4, mask);
8122         }
8123
8124         offset += 4;
8125
8126         return offset;
8127 }
8128
8129 static int
8130 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8131 {
8132         int old_offset, old_sid_offset;
8133         guint32 qsize;
8134
8135         do {
8136                 old_offset=offset;
8137
8138                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8139                 qsize=tvb_get_letohl(tvb, offset);
8140                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8141                 COUNT_BYTES_TRANS_SUBR(4);
8142
8143                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8144                 /* length of SID */
8145                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8146                 COUNT_BYTES_TRANS_SUBR(4);
8147
8148                 /* 16 unknown bytes */
8149                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8150                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8151                             offset, 8, TRUE);
8152                 COUNT_BYTES_TRANS_SUBR(8);
8153
8154                 /* number of bytes for used quota */
8155                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8156                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8157                 COUNT_BYTES_TRANS_SUBR(8);
8158
8159                 /* number of bytes for quota warning */
8160                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8161                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8162                 COUNT_BYTES_TRANS_SUBR(8);
8163
8164                 /* number of bytes for quota limit */
8165                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8166                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8167                 COUNT_BYTES_TRANS_SUBR(8);
8168
8169                 /* SID of the user */
8170                 old_sid_offset=offset;
8171                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8172                 *bcp -= (offset-old_sid_offset);
8173
8174                 if(qsize){
8175                         offset = old_offset+qsize;
8176                 }
8177         }while(qsize);
8178
8179
8180         return offset;
8181 }
8182
8183
8184 static int
8185 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)
8186 {
8187         proto_item *item = NULL;
8188         proto_tree *tree = NULL;
8189         smb_info_t *si;
8190         int old_offset = offset;
8191         guint16 bcp=bc; /* XXX fixme */
8192         struct access_mask_info *ami=NULL;
8193         tvbuff_t *ioctl_tvb;
8194
8195         si = (smb_info_t *)pinfo->private_data;
8196
8197         DISSECTOR_ASSERT(si);
8198
8199         if(parent_tree){
8200                 tvb_ensure_bytes_exist(tvb, offset, bc);
8201                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8202                                 "%s Data",
8203                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8204                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8205         }
8206
8207         switch(ntd->subcmd){
8208         case NT_TRANS_CREATE:
8209                 /* security descriptor */
8210                 if(ntd->sd_len){
8211                         offset = dissect_nt_sec_desc(
8212                                 tvb, offset, pinfo, tree, NULL, TRUE,
8213                                 ntd->sd_len, NULL);
8214                 }
8215
8216                 /* extended attributes */
8217                 if(ntd->ea_len){
8218                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8219                         offset += ntd->ea_len;
8220                 }
8221
8222                 break;
8223         case NT_TRANS_IOCTL:
8224                 /* ioctl data */
8225                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8226                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
8227
8228
8229                 offset += bc;
8230
8231                 break;
8232         case NT_TRANS_SSD:
8233                 if(nti){
8234                         switch(nti->fid_type){
8235                         case SMB_FID_TYPE_FILE:
8236                                 ami= &smb_file_access_mask_info;
8237                                 break;
8238                         case SMB_FID_TYPE_DIR:
8239                                 ami= &smb_dir_access_mask_info;
8240                                 break;
8241                         }
8242                 }
8243
8244                 offset = dissect_nt_sec_desc(
8245                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8246                 break;
8247         case NT_TRANS_NOTIFY:
8248                 break;
8249         case NT_TRANS_RENAME:
8250                 /* XXX not documented */
8251                 break;
8252         case NT_TRANS_QSD:
8253                 break;
8254         case NT_TRANS_GET_USER_QUOTA:
8255                 /* unknown 4 bytes */
8256                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8257                             offset, 4, TRUE);
8258                 offset += 4;
8259
8260                 /* length of SID */
8261                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8262                 offset +=4;
8263
8264                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8265                 break;
8266         case NT_TRANS_SET_USER_QUOTA:
8267                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8268                 break;
8269         }
8270
8271         /* ooops there were data we didnt know how to process */
8272         if((offset-old_offset) < bc){
8273                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8274                     bc - (offset-old_offset), TRUE);
8275                 offset += bc - (offset-old_offset);
8276         }
8277
8278         return offset;
8279 }
8280
8281 static int
8282 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)
8283 {
8284         proto_item *item = NULL;
8285         proto_tree *tree = NULL;
8286         smb_info_t *si;
8287         guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options, create_disposition;
8288         const char *fn;
8289
8290         si = (smb_info_t *)pinfo->private_data;
8291
8292         DISSECTOR_ASSERT(si);
8293
8294         if(parent_tree){
8295                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8296                                 "%s Parameters",
8297                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8298                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8299         }
8300
8301         switch(ntd->subcmd){
8302         case NT_TRANS_CREATE:
8303                 /* Create flags */
8304                 create_flags=tvb_get_letohl(tvb, offset);
8305                 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8306                 bc -= 4;
8307
8308                 /* root directory fid */
8309                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8310                 COUNT_BYTES(4);
8311
8312                 /* nt access mask */
8313                 access_mask=tvb_get_letohl(tvb, offset);
8314                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8315                 bc -= 4;
8316
8317                 /* allocation size */
8318                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8319                 COUNT_BYTES(8);
8320
8321                 /* Extended File Attributes */
8322                 file_attributes=tvb_get_letohl(tvb, offset);
8323                 offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
8324                 bc -= 4;
8325
8326                 /* share access */
8327                 share_access=tvb_get_letohl(tvb, offset);
8328                 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8329                 bc -= 4;
8330
8331                 /* create disposition */
8332                 create_disposition=tvb_get_letohl(tvb, offset);
8333                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8334                 COUNT_BYTES(4);
8335
8336                 /* create options */
8337                 create_options=tvb_get_letohl(tvb, offset);
8338                 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8339                 bc -= 4;
8340
8341                 /* sd length */
8342                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8343                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8344                 COUNT_BYTES(4);
8345
8346                 /* ea length */
8347                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8348                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8349                 COUNT_BYTES(4);
8350
8351                 /* file name len */
8352                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8353                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8354                 COUNT_BYTES(4);
8355
8356                 /* impersonation level */
8357                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8358                 COUNT_BYTES(4);
8359
8360                 /* security flags */
8361                 offset = dissect_nt_security_flags(tvb, tree, offset);
8362                 bc -= 1;
8363
8364                 /* file name */
8365                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8366                 if (fn != NULL) {
8367                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8368                                 fn);
8369                         COUNT_BYTES(fn_len);
8370                 }
8371
8372                 break;
8373         case NT_TRANS_IOCTL:
8374                 break;
8375         case NT_TRANS_SSD: {
8376                 guint16 fid;
8377                 smb_fid_info_t *fid_info;
8378
8379                 /* fid */
8380                 fid = tvb_get_letohs(tvb, offset);
8381                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8382                 offset += 2;
8383                 if(nti){
8384                         if(fid_info){
8385                                 nti->fid_type=fid_info->type;
8386                         } else {
8387                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8388                         }
8389                 }
8390
8391                 /* 2 reserved bytes */
8392                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8393                 offset += 2;
8394
8395                 /* security information */
8396                 offset = dissect_security_information_mask(tvb, tree, offset);
8397                 break;
8398         }
8399         case NT_TRANS_NOTIFY:
8400                 break;
8401         case NT_TRANS_RENAME:
8402                 /* XXX not documented */
8403                 break;
8404         case NT_TRANS_QSD: {
8405                 guint16 fid;
8406                 smb_fid_info_t *fid_info;
8407
8408                 /* fid */
8409                 fid = tvb_get_letohs(tvb, offset);
8410                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8411                 offset += 2;
8412                 if(nti){
8413                         if(fid_info){
8414                                 nti->fid_type=fid_info->type;
8415                         } else {
8416                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8417                         }
8418                 }
8419
8420                 /* 2 reserved bytes */
8421                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8422                 offset += 2;
8423
8424                 /* security information */
8425                 offset = dissect_security_information_mask(tvb, tree, offset);
8426                 break;
8427         }
8428         case NT_TRANS_GET_USER_QUOTA:
8429                 /* not decoded yet */
8430                 break;
8431         case NT_TRANS_SET_USER_QUOTA:
8432                 /* not decoded yet */
8433                 break;
8434         }
8435
8436         return offset;
8437 }
8438
8439 static int
8440 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8441 {
8442         proto_item *item = NULL;
8443         proto_tree *tree = NULL;
8444         int old_offset = offset;
8445         smb_info_t *si;
8446         smb_nt_transact_info_t *nti;
8447         smb_saved_info_t *sip;
8448
8449
8450         si = (smb_info_t *)pinfo->private_data;
8451         DISSECTOR_ASSERT(si);
8452         sip = si->sip;
8453         DISSECTOR_ASSERT(sip);
8454         nti=sip->extra_info;
8455
8456
8457         if(parent_tree){
8458                 tvb_ensure_bytes_exist(tvb, offset, len);
8459                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8460                                 "%s Setup",
8461                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8462                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8463         }
8464
8465         switch(ntd->subcmd){
8466         case NT_TRANS_CREATE:
8467                 break;
8468         case NT_TRANS_IOCTL: {
8469                 guint16 fid;
8470
8471                 /* function code */
8472                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
8473
8474                 /* fid */
8475                 fid = tvb_get_letohs(tvb, offset);
8476                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8477                 offset += 2;
8478
8479                 /* isfsctl */
8480                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8481                 offset += 1;
8482
8483                 /* isflags */
8484                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8485
8486                 break;
8487         }
8488         case NT_TRANS_SSD:
8489                 break;
8490         case NT_TRANS_NOTIFY: {
8491                 guint16 fid;
8492
8493                 /* completion filter */
8494                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8495
8496                 /* fid */
8497                 fid = tvb_get_letohs(tvb, offset);
8498                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8499                 offset += 2;
8500
8501                 /* watch tree */
8502                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8503                 offset += 1;
8504
8505                 /* reserved byte */
8506                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8507                 offset += 1;
8508
8509                 break;
8510         }
8511         case NT_TRANS_RENAME:
8512                 /* XXX not documented */
8513                 break;
8514         case NT_TRANS_QSD:
8515                 break;
8516         case NT_TRANS_GET_USER_QUOTA:
8517                 /* not decoded yet */
8518                 break;
8519         case NT_TRANS_SET_USER_QUOTA:
8520                 /* not decoded yet */
8521                 break;
8522         }
8523
8524         return old_offset+len;
8525 }
8526
8527
8528 static int
8529 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8530 {
8531         guint8 wc, sc;
8532         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8533         smb_info_t *si;
8534         smb_saved_info_t *sip;
8535         int subcmd;
8536         nt_trans_data ntd;
8537         guint16 bc;
8538         guint32 padcnt;
8539         smb_nt_transact_info_t *nti=NULL;
8540
8541         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8542
8543         si = (smb_info_t *)pinfo->private_data;
8544         DISSECTOR_ASSERT(si);
8545         sip = si->sip;
8546
8547         WORD_COUNT;
8548
8549         if(wc>=19){
8550                 /* primary request */
8551                 /* max setup count */
8552                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8553                 offset += 1;
8554
8555                 /* 2 reserved bytes */
8556                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8557                 offset += 2;
8558         } else {
8559                 /* secondary request */
8560                 /* 3 reserved bytes */
8561                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8562                 offset += 3;
8563         }
8564
8565
8566         /* total param count */
8567         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8568         offset += 4;
8569
8570         /* total data count */
8571         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8572         offset += 4;
8573
8574         if(wc>=19){
8575                 /* primary request */
8576                 /* max param count */
8577                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8578                 offset += 4;
8579
8580                 /* max data count */
8581                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8582                 offset += 4;
8583         }
8584
8585         /* param count */
8586         pc = tvb_get_letohl(tvb, offset);
8587         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8588         offset += 4;
8589
8590         /* param offset */
8591         po = tvb_get_letohl(tvb, offset);
8592         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8593         offset += 4;
8594
8595         /* param displacement */
8596         if(wc>=19){
8597                 /* primary request*/
8598                 pd = 0;
8599         } else {
8600                 /* secondary request */
8601                 pd = tvb_get_letohl(tvb, offset);
8602                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8603                 offset += 4;
8604         }
8605
8606         /* data count */
8607         dc = tvb_get_letohl(tvb, offset);
8608         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8609         offset += 4;
8610
8611         /* data offset */
8612         od = tvb_get_letohl(tvb, offset);
8613         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8614         offset += 4;
8615
8616         /* data displacement */
8617         if(wc>=19){
8618                 /* primary request */
8619                 dd = 0;
8620         } else {
8621                 /* secondary request */
8622                 dd = tvb_get_letohl(tvb, offset);
8623                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8624                 offset += 4;
8625         }
8626
8627         /* setup count */
8628         if(wc>=19){
8629                 /* primary request */
8630                 sc = tvb_get_guint8(tvb, offset);
8631                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8632                 offset += 1;
8633         } else {
8634                 /* secondary request */
8635                 sc = 0;
8636         }
8637
8638         /* function */
8639         if(wc>=19){
8640                 /* primary request */
8641                 subcmd = tvb_get_letohs(tvb, offset);
8642                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8643                 if(check_col(pinfo->cinfo, COL_INFO)){
8644                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8645                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8646                 }
8647                 ntd.subcmd = subcmd;
8648                 if (!si->unidir && sip) {
8649                         if(!pinfo->fd->flags.visited){
8650                                 /*
8651                                  * Allocate a new smb_nt_transact_info_t
8652                                  * structure.
8653                                  */
8654                                 nti = se_alloc(sizeof(smb_nt_transact_info_t));
8655                                 nti->subcmd = subcmd;
8656                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8657                                 sip->extra_info = nti;
8658                                 sip->extra_info_type = SMB_EI_NTI;
8659                         } else {
8660                                 if(sip->extra_info_type == SMB_EI_NTI){
8661                                         nti=sip->extra_info;
8662                                 }
8663                         }
8664                 }
8665         } else {
8666                 /* secondary request */
8667                 if(check_col(pinfo->cinfo, COL_INFO)){
8668                         col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
8669                 }
8670         }
8671         offset += 2;
8672
8673         /* this is a padding byte */
8674         if(offset%1){
8675                 /* pad byte */
8676                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8677                 offset += 1;
8678         }
8679
8680         /* if there were any setup bytes, decode them */
8681         if(sc){
8682                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8683                 offset += sc*2;
8684         }
8685
8686         BYTE_COUNT;
8687
8688         /* parameters */
8689         if(po>(guint32)offset){
8690                 /* We have some initial padding bytes.
8691                 */
8692                 padcnt = po-offset;
8693                 if (padcnt > bc)
8694                         padcnt = bc;
8695                 CHECK_BYTE_COUNT(padcnt);
8696                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8697                 COUNT_BYTES(padcnt);
8698         }
8699         if(pc){
8700                 CHECK_BYTE_COUNT(pc);
8701                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti);
8702                 COUNT_BYTES(pc);
8703         }
8704
8705         /* data */
8706         if(od>(guint32)offset){
8707                 /* We have some initial padding bytes.
8708                 */
8709                 padcnt = od-offset;
8710                 if (padcnt > bc)
8711                         padcnt = bc;
8712                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8713                 COUNT_BYTES(padcnt);
8714         }
8715         if(dc){
8716                 CHECK_BYTE_COUNT(dc);
8717                 dissect_nt_trans_data_request(
8718                         tvb, pinfo, offset, tree, dc, &ntd, nti);
8719                 COUNT_BYTES(dc);
8720         }
8721
8722         END_OF_SMB
8723
8724         return offset;
8725 }
8726
8727
8728
8729 static int
8730 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8731                                int offset, proto_tree *parent_tree, int len,
8732                                nt_trans_data *ntd _U_,
8733                                smb_nt_transact_info_t *nti)
8734 {
8735         proto_item *item = NULL;
8736         proto_tree *tree = NULL;
8737         smb_info_t *si;
8738         guint16 bcp;
8739         struct access_mask_info *ami=NULL;
8740         tvbuff_t *ioctl_tvb;
8741
8742         si = (smb_info_t *)pinfo->private_data;
8743         DISSECTOR_ASSERT(si);
8744
8745         if(parent_tree){
8746                 tvb_ensure_bytes_exist(tvb, offset, len);
8747                 if(nti != NULL){
8748                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8749                                 "%s Data",
8750                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8751                 } else {
8752                         /*
8753                          * We never saw the request to which this is a
8754                          * response.
8755                          */
8756                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8757                                 "Unknown NT Transaction Data (matching request not seen)");
8758                 }
8759                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8760         }
8761
8762         if (nti == NULL) {
8763                 offset += len;
8764                 return offset;
8765         }
8766         switch(nti->subcmd){
8767         case NT_TRANS_CREATE:
8768                 break;
8769         case NT_TRANS_IOCTL:
8770                 /* ioctl data */
8771                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
8772                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
8773
8774                 offset += len;
8775
8776                 break;
8777         case NT_TRANS_SSD:
8778                 break;
8779         case NT_TRANS_NOTIFY:
8780                 break;
8781         case NT_TRANS_RENAME:
8782                 /* XXX not documented */
8783                 break;
8784         case NT_TRANS_QSD:
8785                 if(nti){
8786                         switch(nti->fid_type){
8787                         case SMB_FID_TYPE_FILE:
8788                                 ami= &smb_file_access_mask_info;
8789                                 break;
8790                         case SMB_FID_TYPE_DIR:
8791                                 ami= &smb_dir_access_mask_info;
8792                                 break;
8793                         }
8794                 }
8795                 offset = dissect_nt_sec_desc(
8796                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
8797                 break;
8798         case NT_TRANS_GET_USER_QUOTA:
8799                 bcp=len;
8800                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8801                 break;
8802         case NT_TRANS_SET_USER_QUOTA:
8803                 /* not decoded yet */
8804                 break;
8805         }
8806
8807         return offset;
8808 }
8809
8810 static int
8811 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8812                                 int offset, proto_tree *parent_tree,
8813                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8814 {
8815         proto_item *item = NULL;
8816         proto_tree *tree = NULL;
8817         guint32 fn_len;
8818         const char *fn;
8819         smb_info_t *si;
8820         smb_nt_transact_info_t *nti;
8821         guint16 fid;
8822         int old_offset;
8823         guint32 neo;
8824         int padcnt;
8825         smb_fid_info_t *fid_info=NULL;
8826         guint16 ftype;
8827         guint8  isdir;
8828
8829         si = (smb_info_t *)pinfo->private_data;
8830         DISSECTOR_ASSERT(si);
8831
8832         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8833                 nti = si->sip->extra_info;
8834         else
8835                 nti = NULL;
8836
8837         if(parent_tree){
8838                 tvb_ensure_bytes_exist(tvb, offset, len);
8839                 if(nti != NULL){
8840                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8841                                 "%s Parameters",
8842                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8843                 } else {
8844                         /*
8845                          * We never saw the request to which this is a
8846                          * response.
8847                          */
8848                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8849                                 "Unknown NT Transaction Parameters (matching request not seen)");
8850                 }
8851                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8852         }
8853
8854         if (nti == NULL) {
8855                 offset += len;
8856                 return offset;
8857         }
8858         switch(nti->subcmd){
8859         case NT_TRANS_CREATE:
8860                 /* oplock level */
8861                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8862                 offset += 1;
8863
8864                 /* reserved byte */
8865                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8866                 offset += 1;
8867
8868                 /* fid */
8869                 fid = tvb_get_letohs(tvb, offset);
8870                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
8871                 offset += 2;
8872
8873                 /* create action */
8874                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8875                 offset += 4;
8876
8877                 /* ea error offset */
8878                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8879                 offset += 4;
8880
8881                 /* create time */
8882                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8883                         hf_smb_create_time);
8884
8885                 /* access time */
8886                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8887                         hf_smb_access_time);
8888
8889                 /* last write time */
8890                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8891                         hf_smb_last_write_time);
8892
8893                 /* last change time */
8894                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8895                         hf_smb_change_time);
8896
8897                 /* Extended File Attributes */
8898                 offset = dissect_file_ext_attr(tvb, tree, offset);
8899
8900                 /* allocation size */
8901                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8902                 offset += 8;
8903
8904                 /* end of file */
8905                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8906                 offset += 8;
8907
8908                 /* File Type */
8909                 ftype=tvb_get_letohs(tvb, offset);
8910                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8911                 offset += 2;
8912
8913                 /* device state */
8914                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8915
8916                 /* is directory */
8917                 isdir=tvb_get_guint8(tvb, offset);
8918                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8919                 offset += 1;
8920
8921                 /* Try to remember the type of this fid so that we can dissect
8922                  * any future security descriptor (access mask) properly
8923                  */
8924                 if(ftype==0){
8925                         if(isdir==0){
8926                                 if(fid_info){
8927                                         fid_info->type=SMB_FID_TYPE_FILE;
8928                                 }
8929                         } else {
8930                                 if(fid_info){
8931                                         fid_info->type=SMB_FID_TYPE_DIR;
8932                                 }
8933                         }
8934                 }
8935                 if(ftype==2){
8936                         if(fid_info){
8937                                 fid_info->type=SMB_FID_TYPE_PIPE;
8938                         }
8939                 }
8940                 break;
8941         case NT_TRANS_IOCTL:
8942                 break;
8943         case NT_TRANS_SSD:
8944                 break;
8945         case NT_TRANS_NOTIFY:
8946                 while(len){
8947                         old_offset = offset;
8948
8949                         /* next entry offset */
8950                         neo = tvb_get_letohl(tvb, offset);
8951                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8952                         COUNT_BYTES(4);
8953                         len -= 4;
8954                         /* broken implementations */
8955                         if(len<0)break;
8956
8957                         /* action */
8958                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8959                         COUNT_BYTES(4);
8960                         len -= 4;
8961                         /* broken implementations */
8962                         if(len<0)break;
8963
8964                         /* file name len */
8965                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8966                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8967                         COUNT_BYTES(4);
8968                         len -= 4;
8969                         /* broken implementations */
8970                         if(len<0)break;
8971
8972                         /* file name */
8973                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8974                         if (fn == NULL)
8975                                 break;
8976                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8977                                 fn);
8978                         COUNT_BYTES(fn_len);
8979                         len -= fn_len;
8980                         /* broken implementations */
8981                         if(len<0)break;
8982
8983                         if (neo == 0)
8984                                 break;  /* no more structures */
8985
8986                         /* skip to next structure */
8987                         padcnt = (old_offset + neo) - offset;
8988                         if (padcnt < 0) {
8989                                 /*
8990                                  * XXX - this is bogus; flag it?
8991                                  */
8992                                 padcnt = 0;
8993                         }
8994                         if (padcnt != 0) {
8995                                 COUNT_BYTES(padcnt);
8996                                 len -= padcnt;
8997                                 /* broken implementations */
8998                                 if(len<0)break;
8999                         }
9000                 }
9001                 break;
9002         case NT_TRANS_RENAME:
9003                 /* XXX not documented */
9004                 break;
9005         case NT_TRANS_QSD:
9006                 /*
9007                  * This appears to be the size of the security
9008                  * descriptor; the calling sequence of
9009                  * "ZwQuerySecurityObject()" suggests that it would
9010                  * be.  The actual security descriptor wouldn't
9011                  * follow if the max data count in the request
9012                  * was smaller; this lets the client know how
9013                  * big a buffer it needs to provide.
9014                  */
9015                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
9016                 offset += 4;
9017                 break;
9018         case NT_TRANS_GET_USER_QUOTA:
9019                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
9020                         tvb_get_letohl(tvb, offset));
9021                 offset += 4;
9022                 break;
9023         case NT_TRANS_SET_USER_QUOTA:
9024                 /* not decoded yet */
9025                 break;
9026         }
9027
9028         return offset;
9029 }
9030
9031 static int
9032 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
9033                                 int offset, proto_tree *parent_tree,
9034                                 int len, nt_trans_data *ntd _U_)
9035 {
9036         proto_item *item = NULL;
9037         proto_tree *tree = NULL;
9038         smb_info_t *si;
9039         smb_nt_transact_info_t *nti;
9040
9041         si = (smb_info_t *)pinfo->private_data;
9042         DISSECTOR_ASSERT(si);
9043
9044         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9045                 nti = si->sip->extra_info;
9046         else
9047                 nti = NULL;
9048
9049         if(parent_tree){
9050                 tvb_ensure_bytes_exist(tvb, offset, len);
9051                 if(nti != NULL){
9052                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9053                                 "%s Setup",
9054                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
9055                 } else {
9056                         /*
9057                          * We never saw the request to which this is a
9058                          * response.
9059                          */
9060                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9061                                 "Unknown NT Transaction Setup (matching request not seen)");
9062                 }
9063                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
9064         }
9065
9066         if (nti == NULL) {
9067                 offset += len;
9068                 return offset;
9069         }
9070         switch(nti->subcmd){
9071         case NT_TRANS_CREATE:
9072                 break;
9073         case NT_TRANS_IOCTL:
9074                 break;
9075         case NT_TRANS_SSD:
9076                 break;
9077         case NT_TRANS_NOTIFY:
9078                 break;
9079         case NT_TRANS_RENAME:
9080                 /* XXX not documented */
9081                 break;
9082         case NT_TRANS_QSD:
9083                 break;
9084         case NT_TRANS_GET_USER_QUOTA:
9085                 /* not decoded yet */
9086                 break;
9087         case NT_TRANS_SET_USER_QUOTA:
9088                 /* not decoded yet */
9089                 break;
9090         }
9091
9092         return offset;
9093 }
9094
9095 static int
9096 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9097 {
9098         guint8 wc, sc;
9099         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
9100         guint32 td=0, tp=0;
9101         smb_info_t *si;
9102         smb_nt_transact_info_t *nti=NULL;
9103         static nt_trans_data ntd;
9104         guint16 bc;
9105         gint32 padcnt;
9106         fragment_data *r_fd = NULL;
9107         tvbuff_t *pd_tvb=NULL;
9108         gboolean save_fragmented;
9109
9110         si = (smb_info_t *)pinfo->private_data;
9111         DISSECTOR_ASSERT(si);
9112
9113         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9114                 nti = si->sip->extra_info;
9115         else
9116                 nti = NULL;
9117
9118         /* primary request */
9119         if(nti != NULL){
9120                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9121                 if(check_col(pinfo->cinfo, COL_INFO)){
9122                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9123                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
9124                 }
9125         } else {
9126                 proto_tree_add_text(tree, tvb, offset, 0,
9127                         "Function: <unknown function - could not find matching request>");
9128                 if(check_col(pinfo->cinfo, COL_INFO)){
9129                         col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
9130                 }
9131         }
9132
9133         WORD_COUNT;
9134
9135         /* 3 reserved bytes */
9136         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9137         offset += 3;
9138
9139         /* total param count */
9140         tp = tvb_get_letohl(tvb, offset);
9141         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9142         offset += 4;
9143
9144         /* total data count */
9145         td = tvb_get_letohl(tvb, offset);
9146         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9147         offset += 4;
9148
9149         /* param count */
9150         pc = tvb_get_letohl(tvb, offset);
9151         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9152         offset += 4;
9153
9154         /* param offset */
9155         po = tvb_get_letohl(tvb, offset);
9156         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9157         offset += 4;
9158
9159         /* param displacement */
9160         pd = tvb_get_letohl(tvb, offset);
9161         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9162         offset += 4;
9163
9164         /* data count */
9165         dc = tvb_get_letohl(tvb, offset);
9166         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9167         offset += 4;
9168
9169         /* data offset */
9170         od = tvb_get_letohl(tvb, offset);
9171         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9172         offset += 4;
9173
9174         /* data displacement */
9175         dd = tvb_get_letohl(tvb, offset);
9176         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9177         offset += 4;
9178
9179         /* setup count */
9180         sc = tvb_get_guint8(tvb, offset);
9181         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9182         offset += 1;
9183
9184         /* setup data */
9185         if(sc){
9186                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
9187                 offset += sc*2;
9188         }
9189
9190         BYTE_COUNT;
9191
9192         /* reassembly of SMB NT Transaction data payload.
9193            In this section we do reassembly of both the data and parameters
9194            blocks of the SMB transaction command.
9195         */
9196         save_fragmented = pinfo->fragmented;
9197         /* do we need reassembly? */
9198         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
9199                 /* oh yeah, either data or parameter section needs
9200                    reassembly...
9201                 */
9202                 pinfo->fragmented = TRUE;
9203                 if(smb_trans_reassembly){
9204                         /* ...and we were told to do reassembly */
9205                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
9206                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9207                                                              po, pc, pd, td+tp);
9208
9209                         }
9210                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
9211                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9212                                                              od, dc, dd+tp, td+tp);
9213                         }
9214                 }
9215         }
9216
9217         /* if we got a reassembled fd structure from the reassembly routine we
9218            must create pd_tvb from it
9219         */
9220         if(r_fd){
9221         proto_item *frag_tree_item;
9222
9223                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
9224                                              r_fd->datalen);
9225                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
9226                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9227
9228                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9229         }
9230
9231
9232         if(pd_tvb){
9233           /* we have reassembled data, grab param and data from there */
9234           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9235                                           &ntd, (guint16) tvb_length(pd_tvb));
9236           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
9237         } else {
9238           /* we do not have reassembled data, just use what we have in the
9239              packet as well as we can */
9240           /* parameters */
9241           if(po>(guint32)offset){
9242             /* We have some initial padding bytes.
9243              */
9244             padcnt = po-offset;
9245             if (padcnt > bc)
9246               padcnt = bc;
9247             CHECK_BYTE_COUNT(padcnt);
9248             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9249             COUNT_BYTES(padcnt);
9250           }
9251           if(pc){
9252             CHECK_BYTE_COUNT(pc);
9253             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
9254             COUNT_BYTES(pc);
9255           }
9256
9257           /* data */
9258           if(od>(guint32)offset){
9259             /* We have some initial padding bytes.
9260              */
9261             padcnt = od-offset;
9262             if (padcnt > bc)
9263               padcnt = bc;
9264             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9265             COUNT_BYTES(padcnt);
9266           }
9267           if(dc){
9268             CHECK_BYTE_COUNT(dc);
9269             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti);
9270             COUNT_BYTES(dc);
9271           }
9272         }
9273         pinfo->fragmented = save_fragmented;
9274
9275         END_OF_SMB
9276
9277         return offset;
9278 }
9279
9280 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9281    NT Transaction command  ends here
9282    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9283
9284 static const value_string print_mode_vals[] = {
9285         {0,     "Text Mode"},
9286         {1,     "Graphics Mode"},
9287         {0, NULL}
9288 };
9289
9290 static int
9291 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9292 {
9293         smb_info_t *si = pinfo->private_data;
9294         int fn_len;
9295         const char *fn;
9296         guint8 wc;
9297         guint16 bc;
9298
9299         DISSECTOR_ASSERT(si);
9300
9301         WORD_COUNT;
9302
9303         /* setup len */
9304         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9305         offset += 2;
9306
9307         /* print mode */
9308         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9309         offset += 2;
9310
9311         BYTE_COUNT;
9312
9313         /* buffer format */
9314         CHECK_BYTE_COUNT(1);
9315         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9316         COUNT_BYTES(1);
9317
9318         /* print identifier */
9319         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9320         if (fn == NULL)
9321                 goto endofcommand;
9322         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9323                 fn);
9324         COUNT_BYTES(fn_len);
9325
9326         END_OF_SMB
9327
9328         return offset;
9329 }
9330
9331
9332 static int
9333 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9334 {
9335         int cnt;
9336         guint8 wc;
9337         guint16 bc, fid;
9338
9339         WORD_COUNT;
9340
9341         /* fid */
9342         fid = tvb_get_letohs(tvb, offset);
9343         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
9344         offset += 2;
9345
9346         BYTE_COUNT;
9347
9348         /* buffer format */
9349         CHECK_BYTE_COUNT(1);
9350         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9351         COUNT_BYTES(1);
9352
9353         /* data len */
9354         CHECK_BYTE_COUNT(2);
9355         cnt = tvb_get_letohs(tvb, offset);
9356         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9357         COUNT_BYTES(2);
9358
9359         /* file data */
9360         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9361
9362         END_OF_SMB
9363
9364         return offset;
9365 }
9366
9367
9368 static const value_string print_status_vals[] = {
9369         {1,     "Held or Stopped"},
9370         {2,     "Printing"},
9371         {3,     "Awaiting print"},
9372         {4,     "In intercept"},
9373         {5,     "File had error"},
9374         {6,     "Printer error"},
9375         {0, NULL}
9376 };
9377
9378 static int
9379 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9380 {
9381         guint8 wc;
9382         guint16 bc;
9383
9384         WORD_COUNT;
9385
9386         /* max count */
9387         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9388         offset += 2;
9389
9390         /* start index */
9391         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9392         offset += 2;
9393
9394         BYTE_COUNT;
9395
9396         END_OF_SMB
9397
9398         return offset;
9399 }
9400
9401 static int
9402 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9403     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9404 {
9405         proto_item *item = NULL;
9406         proto_tree *tree = NULL;
9407         smb_info_t *si = pinfo->private_data;
9408         int fn_len;
9409         const char *fn;
9410
9411         DISSECTOR_ASSERT(si);
9412
9413         if(parent_tree){
9414                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9415                         "Queue entry");
9416                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9417         }
9418
9419         /* queued time */
9420         CHECK_BYTE_COUNT_SUBR(4);
9421         offset = dissect_smb_datetime(tvb, tree, offset,
9422                 hf_smb_print_queue_date,
9423                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9424         *bcp -= 4;
9425
9426         /* status */
9427         CHECK_BYTE_COUNT_SUBR(1);
9428         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9429         COUNT_BYTES_SUBR(1);
9430
9431         /* spool file number */
9432         CHECK_BYTE_COUNT_SUBR(2);
9433         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9434         COUNT_BYTES_SUBR(2);
9435
9436         /* spool file size */
9437         CHECK_BYTE_COUNT_SUBR(4);
9438         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9439         COUNT_BYTES_SUBR(4);
9440
9441         /* reserved byte */
9442         CHECK_BYTE_COUNT_SUBR(1);
9443         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9444         COUNT_BYTES_SUBR(1);
9445
9446         /* file name */
9447         fn_len = 16;
9448         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9449         CHECK_STRING_SUBR(fn);
9450         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9451                 fn);
9452         COUNT_BYTES_SUBR(fn_len);
9453
9454         *trunc = FALSE;
9455         return offset;
9456 }
9457
9458 static int
9459 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9460 {
9461         guint16 cnt=0, len;
9462         guint8 wc;
9463         guint16 bc;
9464         gboolean trunc;
9465
9466         WORD_COUNT;
9467
9468         /* count */
9469         cnt = tvb_get_letohs(tvb, offset);
9470         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9471         offset += 2;
9472
9473         /* restart index */
9474         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9475         offset += 2;
9476
9477         BYTE_COUNT;
9478
9479         /* buffer format */
9480         CHECK_BYTE_COUNT(1);
9481         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9482         COUNT_BYTES(1);
9483
9484         /* data len */
9485         CHECK_BYTE_COUNT(2);
9486         len = tvb_get_letohs(tvb, offset);
9487         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9488         COUNT_BYTES(2);
9489
9490         /* queue elements */
9491         while(cnt--){
9492                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9493                     &bc, &trunc);
9494                 if (trunc)
9495                         goto endofcommand;
9496         }
9497
9498         END_OF_SMB
9499
9500         return offset;
9501 }
9502
9503
9504 static int
9505 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9506 {
9507         int name_len;
9508         guint16 bc;
9509         guint8 wc;
9510         guint16 message_len;
9511
9512         WORD_COUNT;
9513
9514         BYTE_COUNT;
9515
9516         /* buffer format */
9517         CHECK_BYTE_COUNT(1);
9518         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9519         COUNT_BYTES(1);
9520
9521         /* originator name */
9522         /* XXX - what if this runs past bc? */
9523         name_len = tvb_strsize(tvb, offset);
9524         CHECK_BYTE_COUNT(name_len);
9525         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9526             name_len, TRUE);
9527         COUNT_BYTES(name_len);
9528
9529         /* buffer format */
9530         CHECK_BYTE_COUNT(1);
9531         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9532         COUNT_BYTES(1);
9533
9534         /* destination name */
9535         /* XXX - what if this runs past bc? */
9536         name_len = tvb_strsize(tvb, offset);
9537         CHECK_BYTE_COUNT(name_len);
9538         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9539             name_len, TRUE);
9540         COUNT_BYTES(name_len);
9541
9542         /* buffer format */
9543         CHECK_BYTE_COUNT(1);
9544         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9545         COUNT_BYTES(1);
9546
9547         /* message len */
9548         CHECK_BYTE_COUNT(2);
9549         message_len = tvb_get_letohs(tvb, offset);
9550         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9551             message_len);
9552         COUNT_BYTES(2);
9553
9554         /* message */
9555         CHECK_BYTE_COUNT(message_len);
9556         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9557             TRUE);
9558         COUNT_BYTES(message_len);
9559
9560         END_OF_SMB
9561
9562         return offset;
9563 }
9564
9565 static int
9566 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9567 {
9568         int name_len;
9569         guint16 bc;
9570         guint8 wc;
9571
9572         WORD_COUNT;
9573
9574         BYTE_COUNT;
9575
9576         /* buffer format */
9577         CHECK_BYTE_COUNT(1);
9578         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9579         COUNT_BYTES(1);
9580
9581         /* originator name */
9582         /* XXX - what if this runs past bc? */
9583         name_len = tvb_strsize(tvb, offset);
9584         CHECK_BYTE_COUNT(name_len);
9585         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9586             name_len, TRUE);
9587         COUNT_BYTES(name_len);
9588
9589         /* buffer format */
9590         CHECK_BYTE_COUNT(1);
9591         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9592         COUNT_BYTES(1);
9593
9594         /* destination name */
9595         /* XXX - what if this runs past bc? */
9596         name_len = tvb_strsize(tvb, offset);
9597         CHECK_BYTE_COUNT(name_len);
9598         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9599             name_len, TRUE);
9600         COUNT_BYTES(name_len);
9601
9602         END_OF_SMB
9603
9604         return offset;
9605 }
9606
9607 static int
9608 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9609 {
9610         guint16 bc;
9611         guint8 wc;
9612
9613         WORD_COUNT;
9614
9615         /* message group ID */
9616         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9617         offset += 2;
9618
9619         BYTE_COUNT;
9620
9621         END_OF_SMB
9622
9623         return offset;
9624 }
9625
9626 static int
9627 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9628 {
9629         guint16 bc;
9630         guint8 wc;
9631         guint16 message_len;
9632
9633         WORD_COUNT;
9634
9635         BYTE_COUNT;
9636
9637         /* buffer format */
9638         CHECK_BYTE_COUNT(1);
9639         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9640         COUNT_BYTES(1);
9641
9642         /* message len */
9643         CHECK_BYTE_COUNT(2);
9644         message_len = tvb_get_letohs(tvb, offset);
9645         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9646             message_len);
9647         COUNT_BYTES(2);
9648
9649         /* message */
9650         CHECK_BYTE_COUNT(message_len);
9651         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9652             TRUE);
9653         COUNT_BYTES(message_len);
9654
9655         END_OF_SMB
9656
9657         return offset;
9658 }
9659
9660 static int
9661 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9662 {
9663         int name_len;
9664         guint16 bc;
9665         guint8 wc;
9666
9667         WORD_COUNT;
9668
9669         BYTE_COUNT;
9670
9671         /* buffer format */
9672         CHECK_BYTE_COUNT(1);
9673         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9674         COUNT_BYTES(1);
9675
9676         /* forwarded name */
9677         /* XXX - what if this runs past bc? */
9678         name_len = tvb_strsize(tvb, offset);
9679         CHECK_BYTE_COUNT(name_len);
9680         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9681             name_len, TRUE);
9682         COUNT_BYTES(name_len);
9683
9684         END_OF_SMB
9685
9686         return offset;
9687 }
9688
9689 static int
9690 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9691 {
9692         int name_len;
9693         guint16 bc;
9694         guint8 wc;
9695
9696         WORD_COUNT;
9697
9698         BYTE_COUNT;
9699
9700         /* buffer format */
9701         CHECK_BYTE_COUNT(1);
9702         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9703         COUNT_BYTES(1);
9704
9705         /* machine name */
9706         /* XXX - what if this runs past bc? */
9707         name_len = tvb_strsize(tvb, offset);
9708         CHECK_BYTE_COUNT(name_len);
9709         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9710             name_len, TRUE);
9711         COUNT_BYTES(name_len);
9712
9713         END_OF_SMB
9714
9715         return offset;
9716 }
9717
9718
9719 static int
9720 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9721 {
9722         guint8  wc, cmd=0xff;
9723         guint16 andxoffset=0;
9724         guint16 bc;
9725         smb_info_t *si = pinfo->private_data;
9726         int fn_len;
9727         const char *fn;
9728         guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0, create_disposition=0;
9729
9730         DISSECTOR_ASSERT(si);
9731
9732         WORD_COUNT;
9733
9734         /* next smb command */
9735         cmd = tvb_get_guint8(tvb, offset);
9736         if(cmd!=0xff){
9737                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9738         } else {
9739                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9740         }
9741         offset += 1;
9742
9743         /* reserved byte */
9744         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9745         offset += 1;
9746
9747         /* andxoffset */
9748         andxoffset = tvb_get_letohs(tvb, offset);
9749         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9750         offset += 2;
9751
9752         /* reserved byte */
9753         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9754         offset += 1;
9755
9756         /* file name len */
9757         fn_len = tvb_get_letohs(tvb, offset);
9758         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9759         offset += 2;
9760
9761         /* Create flags */
9762         create_flags=tvb_get_letohl(tvb, offset);
9763         offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
9764
9765         /* root directory fid */
9766         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9767         offset += 4;
9768
9769         /* nt access mask */
9770         access_mask=tvb_get_letohl(tvb, offset);
9771         offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
9772
9773         /* allocation size */
9774         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9775         offset += 8;
9776
9777         /* Extended File Attributes */
9778         file_attributes=tvb_get_letohl(tvb, offset);
9779         offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
9780
9781         /* share access */
9782         share_access=tvb_get_letohl(tvb, offset);
9783         offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
9784
9785         /* create disposition */
9786         create_disposition=tvb_get_letohl(tvb, offset);
9787         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9788         offset += 4;
9789
9790         /* create options */
9791         create_options=tvb_get_letohl(tvb, offset);
9792         offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
9793
9794         /* impersonation level */
9795         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9796         offset += 4;
9797
9798         /* security flags */
9799         offset = dissect_nt_security_flags(tvb, tree, offset);
9800
9801         BYTE_COUNT;
9802
9803         /* file name */
9804         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9805         if (fn == NULL)
9806                 goto endofcommand;
9807         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9808                 fn);
9809         COUNT_BYTES(fn_len);
9810
9811         /* store it for the fid->name/openframe/closeframe matching in
9812          * dissect_smb_fid()   called from the response.
9813          */
9814         if((!pinfo->fd->flags.visited) && si->sip && fn){
9815                 smb_fid_saved_info_t *fsi;
9816
9817                 fsi=se_alloc(sizeof(smb_fid_saved_info_t));
9818                 fsi->filename=se_strdup(fn);
9819                 fsi->create_flags=create_flags;
9820                 fsi->access_mask=access_mask;
9821                 fsi->file_attributes=file_attributes;
9822                 fsi->share_access=share_access;
9823                 fsi->create_options=create_options;
9824                 fsi->create_disposition=create_disposition;
9825
9826                 si->sip->extra_info_type=SMB_EI_FILEDATA;
9827                 si->sip->extra_info=fsi;
9828         }
9829
9830         if (check_col(pinfo->cinfo, COL_INFO)) {
9831                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9832                     format_text(fn, strlen(fn)));
9833         }
9834
9835         END_OF_SMB
9836
9837         if (cmd != 0xff) {      /* there is an andX command */
9838                 if (andxoffset < offset)
9839                         THROW(ReportedBoundsError);
9840                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9841         }
9842
9843         return offset;
9844 }
9845
9846
9847 static int
9848 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9849 {
9850         guint8  wc, cmd=0xff;
9851         guint16 andxoffset=0;
9852         guint16 bc;
9853         guint16 fid=0;
9854         guint16 ftype;
9855         guint8  isdir;
9856         smb_fid_info_t *fid_info=NULL;
9857         smb_info_t              *si;
9858
9859         si = pinfo->private_data;
9860
9861         WORD_COUNT;
9862
9863         /* next smb command */
9864         cmd = tvb_get_guint8(tvb, offset);
9865         if(cmd!=0xff){
9866                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9867         } else {
9868                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9869         }
9870         offset += 1;
9871
9872         /* reserved byte */
9873         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9874         offset += 1;
9875
9876         /* andxoffset */
9877         andxoffset = tvb_get_letohs(tvb, offset);
9878         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9879         offset += 2;
9880
9881         /* oplock level */
9882         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9883         offset += 1;
9884
9885         /* fid */
9886         fid = tvb_get_letohs(tvb, offset);
9887         fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
9888         offset += 2;
9889
9890         /* create action */
9891         /*XXX is this really the same as create disposition in the request? it looks so*/
9892         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9893         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9894         offset += 4;
9895
9896         /* create time */
9897         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
9898
9899         /* access time */
9900         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
9901
9902         /* last write time */
9903         offset = dissect_nt_64bit_time(tvb, tree, offset,
9904                 hf_smb_last_write_time);
9905
9906         /* last change time */
9907         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
9908
9909         /* Extended File Attributes */
9910         offset = dissect_file_ext_attr(tvb, tree, offset);
9911
9912         /* allocation size */
9913         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9914         offset += 8;
9915
9916         /* end of file */
9917         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9918         offset += 8;
9919
9920         /* File Type */
9921         ftype=tvb_get_letohs(tvb, offset);
9922         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9923         offset += 2;
9924
9925         /* IPC State */
9926         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9927
9928         /* is directory */
9929         isdir=tvb_get_guint8(tvb, offset);
9930         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9931         offset += 1;
9932
9933         /* Try to remember the type of this fid so that we can dissect
9934          * any future security descriptor (access mask) properly
9935          */
9936         if(ftype==0){
9937                 if(isdir==0){
9938                         if(fid_info){
9939                                 fid_info->type=SMB_FID_TYPE_FILE;
9940                         }
9941                 } else {
9942                         if(fid_info){
9943                                 fid_info->type=SMB_FID_TYPE_DIR;
9944                         }
9945                 }
9946         }
9947         if(ftype==2){
9948                 if(fid_info){
9949                         fid_info->type=SMB_FID_TYPE_PIPE;
9950                 }
9951         }
9952
9953         BYTE_COUNT;
9954
9955         END_OF_SMB
9956
9957         if (cmd != 0xff) {      /* there is an andX command */
9958                 if (andxoffset < offset)
9959                         THROW(ReportedBoundsError);
9960                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9961         }
9962
9963         /* if there was an error, add a generated filename to the tree */
9964         if(si->nt_status){
9965                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
9966         }
9967
9968         return offset;
9969 }
9970
9971
9972 static int
9973 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9974 {
9975         guint8 wc;
9976         guint16 bc;
9977
9978         WORD_COUNT;
9979
9980         BYTE_COUNT;
9981
9982         END_OF_SMB
9983
9984         return offset;
9985 }
9986
9987 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9988    BEGIN Transaction/Transaction2 Primary and secondary requests
9989    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9990
9991
9992 const value_string trans2_cmd_vals[] = {
9993         { 0x00,         "OPEN2" },
9994         { 0x01,         "FIND_FIRST2" },
9995         { 0x02,         "FIND_NEXT2" },
9996         { 0x03,         "QUERY_FS_INFO" },
9997         { 0x04,         "SET_FS_QUOTA" },
9998         { 0x05,         "QUERY_PATH_INFO" },
9999         { 0x06,         "SET_PATH_INFO" },
10000         { 0x07,         "QUERY_FILE_INFO" },
10001         { 0x08,         "SET_FILE_INFO" },
10002         { 0x09,         "FSCTL" },
10003         { 0x0A,         "IOCTL2" },
10004         { 0x0B,         "FIND_NOTIFY_FIRST" },
10005         { 0x0C,         "FIND_NOTIFY_NEXT" },
10006         { 0x0D,         "CREATE_DIRECTORY" },
10007         { 0x0E,         "SESSION_SETUP" },
10008         { 0x10,         "GET_DFS_REFERRAL" },
10009         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
10010         { 0,    NULL }
10011 };
10012
10013 static const true_false_string tfs_tf_dtid = {
10014         "Also DISCONNECT TID",
10015         "Do NOT disconnect TID"
10016 };
10017 static const true_false_string tfs_tf_owt = {
10018         "One Way Transaction (NO RESPONSE)",
10019         "Two way transaction"
10020 };
10021
10022 static const true_false_string tfs_ff2_backup = {
10023         "Find WITH backup intent",
10024         "No backup intent"
10025 };
10026 static const true_false_string tfs_ff2_continue = {
10027         "CONTINUE search from previous position",
10028         "New search, do NOT continue from previous position"
10029 };
10030 static const true_false_string tfs_ff2_resume = {
10031         "Return RESUME keys",
10032         "Do NOT return resume keys"
10033 };
10034 static const true_false_string tfs_ff2_close_eos = {
10035         "CLOSE search if END OF SEARCH is reached",
10036         "Do NOT close search if end of search reached"
10037 };
10038 static const true_false_string tfs_ff2_close = {
10039         "CLOSE search after this request",
10040         "Do NOT close search after this request"
10041 };
10042
10043 /* used by
10044    TRANS2_FIND_FIRST2
10045 */
10046 static const value_string ff2_il_vals[] = {
10047         { 1,            "Info Standard"},
10048         { 2,            "Info Query EA Size"},
10049         { 3,            "Info Query EAs From List"},
10050         { 0x0101,       "Find File Directory Info"},
10051         { 0x0102,       "Find File Full Directory Info"},
10052         { 0x0103,       "Find File Names Info"},
10053         { 0x0104,       "Find File Both Directory Info"},
10054         { 0x0202,       "Find File UNIX"},
10055         {0, NULL}
10056 };
10057
10058 /* values used by :
10059         TRANS2_QUERY_PATH_INFORMATION
10060         TRANS2_QUERY_FILE_INFORMATION
10061 */
10062 static const value_string qpi_loi_vals[] = {
10063         { 1,            "Info Standard"},
10064         { 2,            "Info Query EA Size"},
10065         { 3,            "Info Query EAs From List"},
10066         { 4,            "Info Query All EAs"},
10067         { 6,            "Info Is Name Valid"},
10068         { 0x0101,       "Query File Basic Info"},
10069         { 0x0102,       "Query File Standard Info"},
10070         { 0x0103,       "Query File EA Info"},
10071         { 0x0104,       "Query File Name Info"},
10072         { 0x0107,       "Query File All Info"},
10073         { 0x0108,       "Query File Alt Name Info"},
10074         { 0x0109,       "Query File Stream Info"},
10075         { 0x010b,       "Query File Compression Info"},
10076         { 0x0200,       "Query File Unix Basic"},
10077         { 0x0201,       "Query File Unix Link"},
10078         { 0x0202,       "Query File Unix Hardlink"},
10079         { 0x0204,       "Query File Posix ACL"},
10080         { 0x0205,       "Query File Posix XATTR"},
10081         { 0x0206,       "Query File Posix Attr Flags"},
10082         { 0x0207,       "Query File Posix Permissions"},
10083         { 0x0208,       "Query File Posix Lock"},
10084         { 1004,         "Query File Basic Info"},
10085         { 1005,         "Query File Standard Info"},
10086         { 1006,         "Query File Internal Info"},
10087         { 1007,         "Query File EA Info"},
10088         { 1009,         "Query File Name Info"},
10089         { 1010,         "Query File Rename Info"},
10090         { 1011,         "Query File Link Info"},
10091         { 1012,         "Query File Names Info"},
10092         { 1013,         "Query File Disposition Info"},
10093         { 1014,         "Query File Position Info"},
10094         { 1015,         "Query File Full EA Info"},
10095         { 1016,         "Query File Mode Info"},
10096         { 1017,         "Query File Alignment Info"},
10097         { 1018,         "Query File All Info"},
10098         { 1019,         "Query File Allocation Info"},
10099         { 1020,         "Query File End of File Info"},
10100         { 1021,         "Query File Alt Name Info"},
10101         { 1022,         "Query File Stream Info"},
10102         { 1023,         "Query File Pipe Info"},
10103         { 1024,         "Query File Pipe Local Info"},
10104         { 1025,         "Query File Pipe Remote Info"},
10105         { 1026,         "Query File Mailslot Query Info"},
10106         { 1027,         "Query File Mailslot Set Info"},
10107         { 1028,         "Query File Compression Info"},
10108         { 1029,         "Query File ObjectID Info"},
10109         { 1030,         "Query File Completion Info"},
10110         { 1031,         "Query File Move Cluster Info"},
10111         { 1032,         "Query File Quota Info"},
10112         { 1033,         "Query File Reparsepoint Info"},
10113         { 1034,         "Query File Network Open Info"},
10114         { 1035,         "Query File Attribute Tag Info"},
10115         { 1036,         "Query File Tracking Info"},
10116         { 1037,         "Query File Maximum Info"},
10117         {0, NULL}
10118 };
10119
10120 /* values used by :
10121         TRANS2_SET_PATH_INFORMATION
10122         TRANS2_SET_FILE_INFORMATION
10123         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10124         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10125         well; note that they're different from the QUERY_PATH_INFORMATION
10126         and QUERY_FILE_INFORMATION values!)
10127 */
10128 static const value_string spi_loi_vals[] = {
10129         { 1,            "Info Standard"},
10130         { 2,            "Info Query EA Size"},
10131         { 4,            "Info Query All EAs"},
10132         { 0x0101,       "Set File Basic Info"},
10133         { 0x0102,       "Set File Disposition Info"},
10134         { 0x0103,       "Set File Allocation Info"},
10135         { 0x0104,       "Set File End Of File Info"},
10136         { 0x0200,       "Set File Unix Basic"},
10137         { 0x0201,       "Set File Unix Link"},
10138         { 0x0202,       "Set File Unix HardLink"},
10139         { 0x0204,       "Set File Unix ACL"},
10140         { 0x0205,       "Set File Unix XATTR"},
10141         { 0x0206,       "Set File Unix Attr Flags"},
10142         { 0x0208,       "Set File Posix Lock"},
10143         { 0x0209,       "Set File Posix Open"},
10144         { 0x020a,       "Set File Posix Unlink"},
10145         { 1004,         "Set File Basic Info"},
10146         { 1010,         "Set Rename Information"},
10147         { 1013,         "Set Disposition Information"},
10148         { 1014,         "Set Position Information"},
10149         { 1016,         "Set Mode Information"},
10150         { 1019,         "Set Allocation Information"},
10151         { 1020,         "Set EOF Information"},
10152         { 1023,         "Set File Pipe Information"},
10153         { 1025,         "Set File Pipe Remote Information"},
10154         { 1029,         "Set Copy On Write Information"},
10155         { 1032,         "Set OLE Class ID Information"},
10156         { 1039,         "Set Inherit Context Index Information"},
10157         { 1040,         "Set OLE Information (?)"},
10158         {0, NULL}
10159 };
10160
10161 static const value_string qfsi_vals[] = {
10162         { 1,            "Info Allocation"},
10163         { 2,            "Info Volume"},
10164         { 0x0101,       "Query FS Label Info"},
10165         { 0x0102,       "Query FS Volume Info"},
10166         { 0x0103,       "Query FS Size Info"},
10167         { 0x0104,       "Query FS Device Info"},
10168         { 0x0105,       "Query FS Attribute Info"},
10169         { 0x0200,       "Unix Query FS Info"},
10170         { 0x0301,       "Mac Query FS Info"},
10171         { 1001,         "Query FS Label Info"},
10172         { 1002,         "Query FS Volume Info"},
10173         { 1003,         "Query FS Size Info"},
10174         { 1004,         "Query FS Device Info"},
10175         { 1005,         "Query FS Attribute Info"},
10176         { 1006,         "Query FS Quota Info"},
10177         { 1007,         "Query Full FS Size Info"},
10178         { 1008,         "Object ID Information"},
10179         {0, NULL}
10180 };
10181
10182 static const value_string nt_rename_vals[] = {
10183         { 0x0103,       "Create Hard Link"},
10184         {0, NULL}
10185 };
10186
10187
10188 static const value_string delete_pending_vals[] = {
10189         {0,     "Normal, no pending delete"},
10190         {1,     "This object has DELETE PENDING"},
10191         {0, NULL}
10192 };
10193
10194 static const value_string alignment_vals[] = {
10195         {0,     "Byte alignment"},
10196         {1,     "Word (16bit) alignment"},
10197         {3,     "Long (32bit) alignment"},
10198         {7,     "8 byte boundary alignment"},
10199         {0x0f,  "16 byte boundary alignment"},
10200         {0x1f,  "32 byte boundary alignment"},
10201         {0x3f,  "64 byte boundary alignment"},
10202         {0x7f,  "128 byte boundary alignment"},
10203         {0xff,  "256 byte boundary alignment"},
10204         {0x1ff, "512 byte boundary alignment"},
10205         {0, NULL}
10206 };
10207
10208 static const true_false_string tfs_marked_for_deletion = {
10209         "File is MARKED FOR DELETION",
10210         "File is NOT marked for deletion"
10211 };
10212
10213 static const true_false_string tfs_get_dfs_server_hold_storage = {
10214         "Referral SERVER HOLDS STORAGE for the file",
10215         "Referral server does NOT hold storage for the file"
10216 };
10217 static const true_false_string tfs_get_dfs_fielding = {
10218         "The server in referral is FIELDING CAPABLE",
10219         "The server in referrals is NOT fielding capable"
10220 };
10221
10222 static const true_false_string tfs_dfs_referral_flags_name_list_referral = {
10223         "A domain/DC referral response",
10224         "NOT a domain/DC referral response"
10225 };
10226
10227 static const true_false_string tfs_dfs_referral_flags_target_set_boundary = {
10228         "The first target in the target set",
10229         "NOT the first target in the target set"
10230 };
10231
10232 static const value_string dfs_referral_server_type_vals[] = {
10233         {0,     "Non-root targets returned"},
10234         {1,     "Root targets returns"},
10235         {0, NULL}
10236 };
10237
10238
10239 static const true_false_string tfs_device_char_removable = {
10240         "This is a REMOVABLE device",
10241         "This is NOT a removable device"
10242 };
10243 static const true_false_string tfs_device_char_read_only = {
10244         "This is a READ-ONLY device",
10245         "This is NOT a read-only device"
10246 };
10247 static const true_false_string tfs_device_char_floppy = {
10248         "This is a FLOPPY DISK device",
10249         "This is NOT a floppy disk device"
10250 };
10251 static const true_false_string tfs_device_char_write_once = {
10252         "This is a WRITE-ONCE device",
10253         "This is NOT a write-once device"
10254 };
10255 static const true_false_string tfs_device_char_remote = {
10256         "This is a REMOTE device",
10257         "This is NOT a remote device"
10258 };
10259 static const true_false_string tfs_device_char_mounted = {
10260         "This device is MOUNTED",
10261         "This device is NOT mounted"
10262 };
10263 static const true_false_string tfs_device_char_virtual = {
10264         "This is a VIRTUAL device",
10265         "This is NOT a virtual device"
10266 };
10267
10268
10269 static const true_false_string tfs_fs_attr_css = {
10270         "This FS supports CASE SENSITIVE SEARCHes",
10271         "This FS does NOT support case sensitive searches"
10272 };
10273 static const true_false_string tfs_fs_attr_cpn = {
10274         "This FS supports CASE PRESERVED NAMES",
10275         "This FS does NOT support case preserved names"
10276 };
10277 static const true_false_string tfs_fs_attr_uod = {
10278         "This FS supports UNICODE NAMES",
10279         "This FS does NOT support unicode names"
10280 };
10281 static const true_false_string tfs_fs_attr_pacls = {
10282         "This FS supports PERSISTENT ACLs",
10283         "This FS does NOT support persistent acls"
10284 };
10285 static const true_false_string tfs_fs_attr_fc = {
10286         "This FS supports COMPRESSED FILES",
10287         "This FS does NOT support compressed files"
10288 };
10289 static const true_false_string tfs_fs_attr_vq = {
10290         "This FS supports VOLUME QUOTAS",
10291         "This FS does NOT support volume quotas"
10292 };
10293 static const true_false_string tfs_fs_attr_srp = {
10294         "This FS supports REPARSE POINTS",
10295         "This FS does NOT support reparse points"
10296 };
10297 static const true_false_string tfs_fs_attr_srs = {
10298         "This FS supports REMOTE STORAGE",
10299         "This FS does NOT support remote storage"
10300 };
10301 static const true_false_string tfs_fs_attr_ssf = {
10302         "This FS supports SPARSE FILES",
10303         "This FS does NOT support sparse files"
10304 };
10305 static const true_false_string tfs_fs_attr_sla = {
10306         "This FS supports LFN APIs",
10307         "This FS does NOT support lfn apis"
10308 };
10309 static const true_false_string tfs_fs_attr_vic = {
10310         "This FS VOLUME IS COMPRESSED",
10311         "This FS volume is NOT compressed"
10312 };
10313 static const true_false_string tfs_fs_attr_soids = {
10314         "This FS supports OIDs",
10315         "This FS does NOT support OIDs"
10316 };
10317 static const true_false_string tfs_fs_attr_se = {
10318         "This FS supports ENCRYPTION",
10319         "This FS does NOT support encryption"
10320 };
10321 static const true_false_string tfs_fs_attr_ns = {
10322         "This FS supports NAMED STREAMS",
10323         "This FS does NOT support named streams"
10324 };
10325 static const true_false_string tfs_fs_attr_rov = {
10326         "This is a READ ONLY VOLUME",
10327         "This is a read/write volume"
10328 };
10329
10330 #define FF2_RESUME      0x0004
10331
10332 static int
10333 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10334 {
10335         guint16 mask;
10336         proto_item *item = NULL;
10337         proto_tree *tree = NULL;
10338         smb_info_t *si;
10339         smb_transact2_info_t *t2i;
10340
10341         mask = tvb_get_letohs(tvb, offset);
10342
10343         si = (smb_info_t *)pinfo->private_data;
10344         DISSECTOR_ASSERT(si);
10345
10346         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
10347                 t2i = si->sip->extra_info;
10348                 if (t2i != NULL) {
10349                         if (!pinfo->fd->flags.visited)
10350                                 t2i->resume_keys = (mask & FF2_RESUME);
10351                 }
10352         }
10353
10354         if(parent_tree){
10355                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10356                         "Flags: 0x%04x", mask);
10357                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10358
10359                 proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10360                         tvb, offset, 2, mask);
10361                 proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10362                         tvb, offset, 2, mask);
10363                 proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10364                         tvb, offset, 2, mask);
10365                 proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10366                         tvb, offset, 2, mask);
10367                 proto_tree_add_boolean(tree, hf_smb_ff2_close,
10368                         tvb, offset, 2, mask);
10369         }
10370
10371         offset += 2;
10372
10373         return offset;
10374 }
10375
10376 #if 0
10377 static int
10378 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10379 {
10380         guint16 mask;
10381         proto_item *item;
10382         proto_tree *tree;
10383
10384         mask = tvb_get_letohs(tvb, offset);
10385
10386         if(parent_tree){
10387                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10388                         "IO Flag: 0x%04x", mask);
10389                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10390
10391                 proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10392                         tvb, offset, 2, mask);
10393                 proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10394                         tvb, offset, 2, mask);
10395         }
10396
10397         offset += 2;
10398
10399         return offset;
10400 }
10401 #endif
10402
10403 static int
10404 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10405     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10406 {
10407         proto_item *item = NULL;
10408         proto_tree *tree = NULL;
10409         smb_info_t *si;
10410         smb_transact2_info_t *t2i;
10411         int fn_len;
10412         const char *fn;
10413
10414         si = (smb_info_t *)pinfo->private_data;
10415         DISSECTOR_ASSERT(si);
10416
10417         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
10418                 t2i = si->sip->extra_info;
10419         else
10420                 t2i = NULL;
10421
10422         if(parent_tree){
10423                 tvb_ensure_bytes_exist(tvb, offset, bc);
10424                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10425                                 "%s Parameters",
10426                                 val_to_str(subcmd, trans2_cmd_vals,
10427                                            "Unknown (0x%02x)"));
10428                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10429         }
10430
10431         switch(subcmd){
10432         case 0x00:      /*TRANS2_OPEN2*/
10433                 /* open flags */
10434                 CHECK_BYTE_COUNT_TRANS(2);
10435                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10436                 bc -= 2;
10437
10438                 /* desired access */
10439                 CHECK_BYTE_COUNT_TRANS(2);
10440                 offset = dissect_access(tvb, tree, offset, "Desired");
10441                 bc -= 2;
10442
10443                 /* Search Attributes */
10444                 CHECK_BYTE_COUNT_TRANS(2);
10445                 offset = dissect_search_attributes(tvb, tree, offset);
10446                 bc -= 2;
10447
10448                 /* File Attributes */
10449                 CHECK_BYTE_COUNT_TRANS(2);
10450                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10451                 bc -= 2;
10452
10453                 /* create time */
10454                 CHECK_BYTE_COUNT_TRANS(4);
10455                 offset = dissect_smb_datetime(tvb, tree, offset,
10456                         hf_smb_create_time,
10457                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10458                         TRUE);
10459                 bc -= 4;
10460
10461                 /* open function */
10462                 CHECK_BYTE_COUNT_TRANS(2);
10463                 offset = dissect_open_function(tvb, tree, offset);
10464                 bc -= 2;
10465
10466                 /* allocation size */
10467                 CHECK_BYTE_COUNT_TRANS(4);
10468                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10469                 COUNT_BYTES_TRANS(4);
10470
10471                 /* 10 reserved bytes */
10472                 CHECK_BYTE_COUNT_TRANS(10);
10473                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10474                 COUNT_BYTES_TRANS(10);
10475
10476                 /* file name */
10477                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10478                 CHECK_STRING_TRANS(fn);
10479                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10480                         fn);
10481                 COUNT_BYTES_TRANS(fn_len);
10482
10483                 if (check_col(pinfo->cinfo, COL_INFO)) {
10484                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10485                             format_text(fn, strlen(fn)));
10486                 }
10487                 break;
10488         case 0x01:      /*TRANS2_FIND_FIRST2*/
10489                 /* Search Attributes */
10490                 CHECK_BYTE_COUNT_TRANS(2);
10491                 offset = dissect_search_attributes(tvb, tree, offset);
10492                 bc -= 2;
10493
10494                 /* search count */
10495                 CHECK_BYTE_COUNT_TRANS(2);
10496                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10497                 COUNT_BYTES_TRANS(2);
10498
10499                 /* Find First2 flags */
10500                 CHECK_BYTE_COUNT_TRANS(2);
10501                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10502                 bc -= 2;
10503
10504                 /* Find First2 information level */
10505                 CHECK_BYTE_COUNT_TRANS(2);
10506                 si->info_level = tvb_get_letohs(tvb, offset);
10507                 if (t2i != NULL && !pinfo->fd->flags.visited)
10508                         t2i->info_level = si->info_level;
10509                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10510                 COUNT_BYTES_TRANS(2);
10511
10512                 /* storage type */
10513                 CHECK_BYTE_COUNT_TRANS(4);
10514                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10515                 COUNT_BYTES_TRANS(4);
10516
10517                 /* search pattern */
10518                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10519                 CHECK_STRING_TRANS(fn);
10520                 if(t2i && !t2i->name){
10521                         t2i->name = se_strdup(fn);
10522                 }
10523                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10524                         fn);
10525                 COUNT_BYTES_TRANS(fn_len);
10526
10527                 if (check_col(pinfo->cinfo, COL_INFO)) {
10528                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10529                             format_text(fn, strlen(fn)));
10530                 }
10531
10532                 break;
10533         case 0x02:      /*TRANS2_FIND_NEXT2*/
10534                 /* sid */
10535                 CHECK_BYTE_COUNT_TRANS(2);
10536                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10537                 COUNT_BYTES_TRANS(2);
10538
10539                 /* search count */
10540                 CHECK_BYTE_COUNT_TRANS(2);
10541                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10542                 COUNT_BYTES_TRANS(2);
10543
10544                 /* Find First2 information level */
10545                 CHECK_BYTE_COUNT_TRANS(2);
10546                 si->info_level = tvb_get_letohs(tvb, offset);
10547                 if (t2i != NULL && !pinfo->fd->flags.visited)
10548                         t2i->info_level = si->info_level;
10549                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10550                 COUNT_BYTES_TRANS(2);
10551
10552                 /* resume key */
10553                 CHECK_BYTE_COUNT_TRANS(4);
10554                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10555                 COUNT_BYTES_TRANS(4);
10556
10557                 /* Find First2 flags */
10558                 CHECK_BYTE_COUNT_TRANS(2);
10559                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10560                 bc -= 2;
10561
10562                 /* file name */
10563                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10564                 CHECK_STRING_TRANS(fn);
10565                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10566                         fn);
10567                 COUNT_BYTES_TRANS(fn_len);
10568
10569                 if (check_col(pinfo->cinfo, COL_INFO)) {
10570                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10571                             format_text(fn, strlen(fn)));
10572                 }
10573
10574                 break;
10575         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10576                 /* level of interest */
10577                 CHECK_BYTE_COUNT_TRANS(2);
10578                 si->info_level = tvb_get_letohs(tvb, offset);
10579                 if (t2i != NULL && !pinfo->fd->flags.visited)
10580                         t2i->info_level = si->info_level;
10581                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10582                 COUNT_BYTES_TRANS(2);
10583
10584                 if (check_col(pinfo->cinfo, COL_INFO))
10585                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10586                                         val_to_str(si->info_level, qfsi_vals,
10587                                                    "Unknown (0x%02x)"));
10588
10589                 break;
10590         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10591                 /* level of interest */
10592                 CHECK_BYTE_COUNT_TRANS(2);
10593                 si->info_level = tvb_get_letohs(tvb, offset);
10594                 if (t2i != NULL && !pinfo->fd->flags.visited)
10595                         t2i->info_level = si->info_level;
10596                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10597                 COUNT_BYTES_TRANS(2);
10598
10599                 if (check_col(pinfo->cinfo, COL_INFO)) {
10600                         col_append_fstr(
10601                                 pinfo->cinfo, COL_INFO, ", %s",
10602                                 val_to_str(si->info_level, qpi_loi_vals,
10603                                            "Unknown (%u)"));
10604                 }
10605
10606                 /* 4 reserved bytes */
10607                 CHECK_BYTE_COUNT_TRANS(4);
10608                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10609                 COUNT_BYTES_TRANS(4);
10610
10611                 /* file name */
10612                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10613                 CHECK_STRING_TRANS(fn);
10614                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10615                         fn);
10616                 COUNT_BYTES_TRANS(fn_len);
10617                 if(t2i && !t2i->name){
10618                         t2i->name = se_strdup(fn);
10619                 }
10620
10621                 if (check_col(pinfo->cinfo, COL_INFO)) {
10622                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10623                             format_text(fn, strlen(fn)));
10624                 }
10625
10626                 break;
10627         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10628                 /* level of interest */
10629                 CHECK_BYTE_COUNT_TRANS(2);
10630                 si->info_level = tvb_get_letohs(tvb, offset);
10631                 if (t2i != NULL && !pinfo->fd->flags.visited)
10632                         t2i->info_level = si->info_level;
10633                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10634                 COUNT_BYTES_TRANS(2);
10635
10636                 /* 4 reserved bytes */
10637                 CHECK_BYTE_COUNT_TRANS(4);
10638                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10639                 COUNT_BYTES_TRANS(4);
10640
10641                 /* file name */
10642                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10643                 CHECK_STRING_TRANS(fn);
10644                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10645                         fn);
10646                 COUNT_BYTES_TRANS(fn_len);
10647
10648                 if (check_col(pinfo->cinfo, COL_INFO)) {
10649                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10650                             format_text(fn, strlen(fn)));
10651                 }
10652
10653                 break;
10654         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10655                 guint16 fid;
10656
10657                 /* fid */
10658                 CHECK_BYTE_COUNT_TRANS(2);
10659                 fid = tvb_get_letohs(tvb, offset);
10660                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10661                 COUNT_BYTES_TRANS(2);
10662
10663                 /* level of interest */
10664                 CHECK_BYTE_COUNT_TRANS(2);
10665                 si->info_level = tvb_get_letohs(tvb, offset);
10666                 if (t2i != NULL && !pinfo->fd->flags.visited)
10667                         t2i->info_level = si->info_level;
10668                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10669                 COUNT_BYTES_TRANS(2);
10670
10671                 if (check_col(pinfo->cinfo, COL_INFO)) {
10672                         col_append_fstr(
10673                                 pinfo->cinfo, COL_INFO, ", %s",
10674                                 val_to_str(si->info_level, qpi_loi_vals,
10675                                            "Unknown (%u)"));
10676                 }
10677
10678                 break;
10679         }
10680         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10681                 guint16 fid;
10682
10683                 /* fid */
10684                 CHECK_BYTE_COUNT_TRANS(2);
10685                 fid = tvb_get_letohs(tvb, offset);
10686                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10687                 COUNT_BYTES_TRANS(2);
10688
10689                 /* level of interest */
10690                 CHECK_BYTE_COUNT_TRANS(2);
10691                 si->info_level = tvb_get_letohs(tvb, offset);
10692                 if (t2i != NULL && !pinfo->fd->flags.visited)
10693                         t2i->info_level = si->info_level;
10694                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10695                 COUNT_BYTES_TRANS(2);
10696
10697 #if 0
10698                 /*
10699                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10700                  * Extensions Version 3.0, Document Version 1.11,
10701                  * July 19, 1990" says this is I/O flags, but it's
10702                  * reserved in the SNIA spec, and some clients appear
10703                  * to leave junk in it.
10704                  *
10705                  * Is this some field used only if a particular
10706                  * dialect was negotiated, so that clients can feel
10707                  * safe not setting it if they haven't negotiated that
10708                  * dialect?  Or do the (non-OS/2) clients simply not care
10709                  * about that particular OS/2-oriented dialect?
10710                  */
10711
10712                 /* IO Flag */
10713                 CHECK_BYTE_COUNT_TRANS(2);
10714                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10715                 bc -= 2;
10716 #else
10717                 /* 2 reserved bytes */
10718                 CHECK_BYTE_COUNT_TRANS(2);
10719                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10720                 COUNT_BYTES_TRANS(2);
10721 #endif
10722
10723                 break;
10724         }
10725         case 0x09:      /*TRANS2_FSCTL*/
10726                 /* this call has no parameter block in the request */
10727
10728                 /*
10729                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10730                  * Extensions Version 3.0, Document Version 1.11,
10731                  * July 19, 1990" says this this contains a
10732                  * "File system specific parameter block".  (That means
10733                  * we may not be able to dissect it in any case.)
10734                  */
10735                 break;
10736         case 0x0a:      /*TRANS2_IOCTL2*/
10737                 /* this call has no parameter block in the request */
10738
10739                 /*
10740                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10741                  * Extensions Version 3.0, Document Version 1.11,
10742                  * July 19, 1990" says this this contains a
10743                  * "Device/function specific parameter block".  (That
10744                  * means we may not be able to dissect it in any case.)
10745                  */
10746                 break;
10747         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10748                 /* Search Attributes */
10749                 CHECK_BYTE_COUNT_TRANS(2);
10750                 offset = dissect_search_attributes(tvb, tree, offset);
10751                 bc -= 2;
10752
10753                 /* Number of changes to wait for */
10754                 CHECK_BYTE_COUNT_TRANS(2);
10755                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10756                 COUNT_BYTES_TRANS(2);
10757
10758                 /* Find Notify information level */
10759                 CHECK_BYTE_COUNT_TRANS(2);
10760                 si->info_level = tvb_get_letohs(tvb, offset);
10761                 if (t2i != NULL && !pinfo->fd->flags.visited)
10762                         t2i->info_level = si->info_level;
10763                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10764                 COUNT_BYTES_TRANS(2);
10765
10766                 /* 4 reserved bytes */
10767                 CHECK_BYTE_COUNT_TRANS(4);
10768                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10769                 COUNT_BYTES_TRANS(4);
10770
10771                 /* file name */
10772                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10773                 CHECK_STRING_TRANS(fn);
10774                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10775                         fn);
10776                 COUNT_BYTES_TRANS(fn_len);
10777
10778                 if (check_col(pinfo->cinfo, COL_INFO)) {
10779                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10780                             format_text(fn, strlen(fn)));
10781                 }
10782
10783                 break;
10784         }
10785         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10786                 /* Monitor handle */
10787                 CHECK_BYTE_COUNT_TRANS(2);
10788                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10789                 COUNT_BYTES_TRANS(2);
10790
10791                 /* Number of changes to wait for */
10792                 CHECK_BYTE_COUNT_TRANS(2);
10793                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10794                 COUNT_BYTES_TRANS(2);
10795
10796                 break;
10797         }
10798         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10799                 /* 4 reserved bytes */
10800                 CHECK_BYTE_COUNT_TRANS(4);
10801                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10802                 COUNT_BYTES_TRANS(4);
10803
10804                 /* dir name */
10805                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10806                         FALSE, FALSE, &bc);
10807                 CHECK_STRING_TRANS(fn);
10808                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10809                         fn);
10810                 COUNT_BYTES_TRANS(fn_len);
10811
10812                 if (check_col(pinfo->cinfo, COL_INFO)) {
10813                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10814                             format_text(fn, strlen(fn)));
10815                 }
10816                 break;
10817         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10818                 /* XXX unknown structure*/
10819                 break;
10820         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10821                 /* referral level */
10822                 CHECK_BYTE_COUNT_TRANS(2);
10823                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10824                 COUNT_BYTES_TRANS(2);
10825
10826                 /* file name */
10827                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10828                 CHECK_STRING_TRANS(fn);
10829                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10830                         fn);
10831                 COUNT_BYTES_TRANS(fn_len);
10832
10833                 if (check_col(pinfo->cinfo, COL_INFO)) {
10834                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10835                             format_text(fn, strlen(fn)));
10836                 }
10837
10838                 break;
10839         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10840                 /* file name */
10841                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10842                 CHECK_STRING_TRANS(fn);
10843                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10844                         fn);
10845                 COUNT_BYTES_TRANS(fn_len);
10846
10847                 if (check_col(pinfo->cinfo, COL_INFO)) {
10848                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10849                             format_text(fn, strlen(fn)));
10850                 }
10851
10852                 break;
10853         }
10854
10855         /* ooops there were data we didnt know how to process */
10856         if(bc != 0){
10857                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10858                 offset += bc;
10859         }
10860
10861         return offset;
10862 }
10863
10864 /*
10865  * XXX - just use "dissect_connect_flags()" here?
10866  */
10867 static guint16
10868 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10869 {
10870         guint16 mask;
10871         proto_item *item;
10872         proto_tree *tree;
10873
10874         mask = tvb_get_letohs(tvb, offset);
10875
10876         if(parent_tree){
10877                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10878                         "Flags: 0x%04x", mask);
10879                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10880
10881                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10882                         tvb, offset, 2, mask);
10883                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10884                         tvb, offset, 2, mask);
10885         }
10886
10887         return mask;
10888 }
10889
10890
10891 static int
10892 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10893 {
10894         guint16 mask;
10895         proto_item *item;
10896         proto_tree *tree;
10897
10898         mask = tvb_get_letohs(tvb, offset);
10899
10900         if(parent_tree){
10901                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10902                         "Flags: 0x%04x", mask);
10903                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10904
10905                 proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10906                         tvb, offset, 2, mask);
10907                 proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10908                         tvb, offset, 2, mask);
10909         }
10910
10911         offset += 2;
10912         return offset;
10913 }
10914
10915 static int
10916 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10917 {
10918         guint16 mask;
10919         proto_item *item;
10920         proto_tree *tree;
10921
10922         mask = tvb_get_letohs(tvb, offset);
10923
10924         if(parent_tree){
10925                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10926                         "Flags: 0x%04x", mask);
10927                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10928
10929                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_name_list_referral,
10930                         tvb, offset, 2, mask);
10931                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_target_set_boundary,
10932                         tvb, offset, 2, mask);
10933         }
10934
10935         offset += 2;
10936
10937         return offset;
10938 }
10939
10940
10941 /* dfs inconsistency data  (4.4.2)
10942 */
10943 static int
10944 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10945     proto_tree *tree, int offset, guint16 *bcp)
10946 {
10947         smb_info_t *si = pinfo->private_data;
10948         int fn_len;
10949         const char *fn;
10950
10951         DISSECTOR_ASSERT(si);
10952
10953         /*XXX shouldn this data hold version and size? unclear from doc*/
10954         /* referral version */
10955         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10956         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10957         COUNT_BYTES_TRANS_SUBR(2);
10958
10959         /* referral size */
10960         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10961         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10962         COUNT_BYTES_TRANS_SUBR(2);
10963
10964         /* referral server type */
10965         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10966         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10967         COUNT_BYTES_TRANS_SUBR(2);
10968
10969         /* referral flags */
10970         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10971         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10972         *bcp -= 2;
10973
10974         /* node name */
10975         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10976         CHECK_STRING_TRANS_SUBR(fn);
10977         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10978                 fn);
10979         COUNT_BYTES_TRANS_SUBR(fn_len);
10980
10981         return offset;
10982 }
10983
10984 static int
10985 dissect_dfs_referral_strings(tvbuff_t *tvb, proto_tree *tree, int hfindex,
10986                              int nstring, int stroffset, int oldoffset, int offset,
10987                              guint16 bc, gboolean unicode, int *end)
10988 {
10989         int istring;
10990         const char *str;
10991         int str_len;       /* string length including the terminating NULL. */
10992
10993         if (stroffset <= oldoffset)
10994                 return oldoffset;
10995
10996         bc -= (stroffset - offset);
10997         for (istring=0; istring<nstring; istring++) {
10998                 if ((gint16)bc > 0) {
10999                         str = get_unicode_or_ascii_string(tvb, &stroffset, unicode, &str_len, FALSE, FALSE, &bc);
11000                         CHECK_STRING_TRANS_SUBR(str);
11001                         proto_tree_add_string(tree, hfindex, tvb, stroffset, str_len, str);
11002                         stroffset += str_len;
11003                         bc -= str_len;
11004                         if (end && (*end < stroffset))
11005                                 *end = stroffset;
11006                 }
11007         }
11008
11009         return offset;
11010 }
11011
11012
11013 static int
11014 dissect_dfs_referral_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11015                             int stroffset, int oldoffset, int offset,
11016                             guint16 bc, gboolean unicode, int *end)
11017 {
11018         return dissect_dfs_referral_strings(tvb, tree, hfindex,
11019                                            1, stroffset, oldoffset, offset,
11020                                            bc, unicode, end);
11021 }
11022
11023 static int
11024 dissect_dfs_referral_entry_v2(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11025                               guint16 refflags _U_, guint16 *bcp, gboolean unicode, int *ucstring_end)
11026 {
11027
11028         guint16 pathoffset;
11029         guint16 altpathoffset;
11030         guint16 nodeoffset;
11031
11032         /* proximity */
11033         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11034         proto_tree_add_item(tree, hf_smb_dfs_referral_proximity, tvb, offset, 4, TRUE);
11035         COUNT_BYTES_TRANS_SUBR(4);
11036
11037         /* ttl */
11038         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11039         proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, TRUE);
11040         COUNT_BYTES_TRANS_SUBR(4);
11041
11042         /* path offset */
11043         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11044         pathoffset = tvb_get_letohs(tvb, offset);
11045         proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11046         COUNT_BYTES_TRANS_SUBR(2);
11047
11048         /* alt path offset */
11049         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11050         altpathoffset = tvb_get_letohs(tvb, offset);
11051         proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11052         COUNT_BYTES_TRANS_SUBR(2);
11053
11054         /* node offset */
11055         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11056         nodeoffset = tvb_get_letohs(tvb, offset);
11057         proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11058         COUNT_BYTES_TRANS_SUBR(2);
11059
11060         /* path */
11061         if (pathoffset) {
11062                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11063                                             pathoffset+oldoffset, oldoffset, offset,
11064                                             *bcp, unicode, ucstring_end);
11065         }
11066
11067         /* alt path */
11068         if (altpathoffset) {
11069                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11070                                             altpathoffset+oldoffset, oldoffset, offset,
11071                                             *bcp, unicode, ucstring_end);
11072         }
11073
11074         /* node */
11075         if (nodeoffset) {
11076                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11077                                             nodeoffset+oldoffset, oldoffset, offset,
11078                                             *bcp, unicode, ucstring_end);
11079         }
11080
11081         return offset;
11082
11083 }
11084
11085
11086 static int
11087 dissect_dfs_referral_entry_v3(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11088                               guint16 refflags, guint16 *bcp, gboolean unicode, int *ucstring_end)
11089 {
11090         guint16 domoffset;
11091         guint16 nexpnames;
11092         guint16 expoffset;
11093         guint16 pathoffset;
11094         guint16 altpathoffset;
11095         guint16 nodeoffset;
11096
11097         /* ttl */
11098         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11099         proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, TRUE);
11100         COUNT_BYTES_TRANS_SUBR(4);
11101
11102         if (refflags & REFENT_FLAGS_NAME_LIST_REFERRAL) {
11103                 /* domain name offset */
11104                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11105                 domoffset = tvb_get_letohs(tvb, offset);
11106                 proto_tree_add_uint(tree, hf_smb_dfs_referral_domain_offset, tvb, offset, 2, domoffset);
11107                 COUNT_BYTES_TRANS_SUBR(2);
11108
11109                 /* number of expanded names*/
11110                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11111                 nexpnames = tvb_get_letohs(tvb, offset);
11112                 proto_tree_add_uint(tree, hf_smb_dfs_referral_number_of_expnames, tvb, offset, 2, nexpnames);
11113                 COUNT_BYTES_TRANS_SUBR(2);
11114
11115                 /* expanded names offset */
11116                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11117                 expoffset = tvb_get_letohs(tvb, offset);
11118                 proto_tree_add_uint(tree, hf_smb_dfs_referral_expnames_offset, tvb, offset, 2, expoffset);
11119                 COUNT_BYTES_TRANS_SUBR(2);
11120
11121                 /* padding: zero or 16 bytes, which should be ignored by clients.
11122                  * we ignore them too.
11123                  */
11124
11125                 /* domain name */
11126                 if (domoffset) {
11127                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_domain_name,
11128                                                     domoffset+oldoffset, oldoffset, offset,
11129                                                     *bcp, unicode, ucstring_end);
11130                 }
11131                 /* expanded names */
11132                 if (expoffset) {
11133                         proto_item *expitem = NULL;
11134                         proto_tree *exptree = NULL;
11135
11136                         expitem = proto_tree_add_text(tree, tvb, offset, *bcp, "Expanded Names");
11137                         exptree = proto_item_add_subtree(expitem, ett_smb_dfs_referral_expnames);
11138
11139                         dissect_dfs_referral_strings(tvb, exptree, hf_smb_dfs_referral_expname,
11140                                                      nexpnames, expoffset+oldoffset, oldoffset, offset,
11141                                                      *bcp, unicode, ucstring_end);
11142                 }
11143         } else {
11144                 /* path offset */
11145                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11146                 pathoffset = tvb_get_letohs(tvb, offset);
11147                 proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11148                 COUNT_BYTES_TRANS_SUBR(2);
11149
11150                 /* alt path offset */
11151                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11152                 altpathoffset = tvb_get_letohs(tvb, offset);
11153                 proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11154                 COUNT_BYTES_TRANS_SUBR(2);
11155
11156                 /* node offset */
11157                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11158                 nodeoffset = tvb_get_letohs(tvb, offset);
11159                 proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11160                 COUNT_BYTES_TRANS_SUBR(2);
11161
11162                 /* service site guid */
11163                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
11164                 proto_tree_add_item(tree, hf_smb_dfs_referral_server_guid, tvb, offset, 16, TRUE);
11165                 COUNT_BYTES_TRANS_SUBR(16);
11166
11167                 /* path */
11168                 if (pathoffset) {
11169                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11170                                                     pathoffset+oldoffset, oldoffset, offset,
11171                                                     *bcp, unicode, ucstring_end);
11172                 }
11173
11174                 /* alt path */
11175                 if (altpathoffset) {
11176                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11177                                                     altpathoffset+oldoffset, oldoffset, offset,
11178                                                     *bcp, unicode, ucstring_end);
11179                 }
11180
11181                 /* node */
11182                 if (nodeoffset) {
11183                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11184                                                     nodeoffset+oldoffset, oldoffset, offset,
11185                                                     *bcp, unicode, ucstring_end);
11186                 }
11187         }
11188
11189         return offset;
11190
11191 }
11192
11193 /* get dfs referral data  (4.4.1)
11194 */
11195 static int
11196 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
11197     proto_tree *tree, int offset, guint16 *bcp)
11198 {
11199         smb_info_t *si = pinfo->private_data;
11200         guint16 numref;
11201         guint16 refsize;
11202         guint16 refflags;
11203         int fn_len;
11204         const char *fn;
11205         int unklen;
11206         int ucstring_end;
11207         int ucstring_len;
11208
11209         DISSECTOR_ASSERT(si);
11210
11211         /* path consumed */
11212         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11213         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
11214         COUNT_BYTES_TRANS_SUBR(2);
11215
11216         /* num referrals */
11217         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11218         numref = tvb_get_letohs(tvb, offset);
11219         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
11220         COUNT_BYTES_TRANS_SUBR(2);
11221
11222         /* get dfs flags */
11223         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11224         offset = dissect_get_dfs_flags(tvb, tree, offset);
11225         *bcp -= 2;
11226
11227         /* XXX - in at least one capture there appears to be 2 bytes
11228            of stuff after the Dfs flags, perhaps so that the header
11229            in front of the referral list is a multiple of 4 bytes long. */
11230         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11231         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
11232         COUNT_BYTES_TRANS_SUBR(2);
11233
11234         /* if there are any referrals */
11235         if(numref){
11236                 proto_item *ref_item = NULL;
11237                 proto_tree *ref_tree = NULL;
11238                 int old_offset=offset;
11239
11240                 if(tree){
11241                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11242                         ref_item = proto_tree_add_text(tree,
11243                                 tvb, offset, *bcp, "Referrals");
11244                         ref_tree = proto_item_add_subtree(ref_item,
11245                                 ett_smb_dfs_referrals);
11246                 }
11247                 ucstring_end = -1;
11248
11249                 while(numref--){
11250                         proto_item *ri = NULL;
11251                         proto_tree *rt = NULL;
11252                         int old_offset=offset;
11253                         guint16 version;
11254
11255                         if(tree){
11256                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
11257                                 ri = proto_tree_add_text(ref_tree,
11258                                         tvb, offset, *bcp, "Referral");
11259                                 rt = proto_item_add_subtree(ri,
11260                                         ett_smb_dfs_referral);
11261                         }
11262
11263                         /* referral version */
11264                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11265                         version = tvb_get_letohs(tvb, offset);
11266                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
11267                                 tvb, offset, 2, version);
11268                         COUNT_BYTES_TRANS_SUBR(2);
11269
11270                         /* referral size */
11271                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11272                         refsize = tvb_get_letohs(tvb, offset);
11273                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
11274                         COUNT_BYTES_TRANS_SUBR(2);
11275
11276                         /* referral server type */
11277                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11278                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
11279                         COUNT_BYTES_TRANS_SUBR(2);
11280
11281                         /* referral flags */
11282                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11283                         refflags = tvb_get_letohs(tvb, offset);
11284                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
11285                         *bcp -= 2;
11286
11287                         switch(version){
11288
11289                         case 1:
11290                                 /* node name */
11291                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11292                                 CHECK_STRING_TRANS_SUBR(fn);
11293                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11294                                         fn);
11295                                 COUNT_BYTES_TRANS_SUBR(fn_len);
11296                                 break;
11297
11298                         case 2:
11299                                 offset = dissect_dfs_referral_entry_v2(tvb, rt, old_offset, offset,
11300                                                                        refflags, bcp, si->unicode, &ucstring_end);
11301                                 break;
11302                         case 3:
11303                                 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset, offset,
11304                                                                        refflags, bcp, si->unicode, &ucstring_end);
11305                                 break;
11306                         case 4:
11307                                 /* V4 is extactly same as V3, except the version number and
11308                                  * one more ReferralEntryFlags */
11309                                 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset, offset,
11310                                                                        refflags, bcp, si->unicode, &ucstring_end);
11311                                 break;
11312                         }
11313
11314                         /*
11315                          * Show anything beyond the length of the referral
11316                          * as unknown data.
11317                          */
11318                         unklen = (old_offset + refsize) - offset;
11319                         if (unklen < 0) {
11320                                 /*
11321                                  * XXX - the length is bogus.
11322                                  */
11323                                 unklen = 0;
11324                         }
11325                         if (unklen != 0) {
11326                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11327                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11328                                     offset, unklen, TRUE);
11329                                 COUNT_BYTES_TRANS_SUBR(unklen);
11330                         }
11331
11332                         proto_item_set_len(ri, offset-old_offset);
11333                 }
11334
11335                 /*
11336                  * Treat the offset past the end of the last Unicode
11337                  * string after the referrals (if any) as the last
11338                  * offset.
11339                  */
11340                 if (ucstring_end > offset) {
11341                         ucstring_len = ucstring_end - offset;
11342                         if (*bcp < ucstring_len)
11343                                 ucstring_len = *bcp;
11344                         offset += ucstring_len;
11345                         *bcp -= ucstring_len;
11346                 }
11347                 proto_item_set_len(ref_item, offset-old_offset);
11348         }
11349
11350         return offset;
11351 }
11352
11353 /* This dissects the standard four 8-byte Windows timestamps ...
11354  */
11355 static int
11356 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11357     packet_info *pinfo _U_, proto_tree *tree,
11358     int offset, guint16 *bcp, gboolean *trunc)
11359 {
11360         /* create time */
11361         CHECK_BYTE_COUNT_SUBR(8);
11362         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11363         *bcp -= 8;
11364
11365         /* access time */
11366         CHECK_BYTE_COUNT_SUBR(8);
11367         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11368         *bcp -= 8;
11369
11370         /* last write time */
11371         CHECK_BYTE_COUNT_SUBR(8);
11372         offset = dissect_nt_64bit_time(tvb, tree, offset,
11373                 hf_smb_last_write_time);
11374         *bcp -= 8;
11375
11376         /* last change time */
11377         CHECK_BYTE_COUNT_SUBR(8);
11378         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11379         *bcp -= 8;
11380
11381         *trunc = FALSE;
11382         return offset;
11383 }
11384
11385 /* this dissects the SMB_INFO_STANDARD
11386    as described in 4.2.16.1
11387 */
11388 static int
11389 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11390     int offset, guint16 *bcp, gboolean *trunc)
11391 {
11392         /* create time */
11393         CHECK_BYTE_COUNT_SUBR(4);
11394         offset = dissect_smb_datetime(tvb, tree, offset,
11395                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11396                 FALSE);
11397         *bcp -= 4;
11398
11399         /* access time */
11400         CHECK_BYTE_COUNT_SUBR(4);
11401         offset = dissect_smb_datetime(tvb, tree, offset,
11402                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11403                 FALSE);
11404         *bcp -= 4;
11405
11406         /* last write time */
11407         CHECK_BYTE_COUNT_SUBR(4);
11408         offset = dissect_smb_datetime(tvb, tree, offset,
11409                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11410                 FALSE);
11411         *bcp -= 4;
11412
11413         /* data size */
11414         CHECK_BYTE_COUNT_SUBR(4);
11415         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11416         COUNT_BYTES_SUBR(4);
11417
11418         /* allocation size */
11419         CHECK_BYTE_COUNT_SUBR(4);
11420         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11421         COUNT_BYTES_SUBR(4);
11422
11423         /* File Attributes */
11424         CHECK_BYTE_COUNT_SUBR(2);
11425         offset = dissect_file_attributes(tvb, tree, offset, 2);
11426         *bcp -= 2;
11427
11428         /* ea length */
11429         CHECK_BYTE_COUNT_SUBR(4);
11430         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11431         COUNT_BYTES_SUBR(4);
11432
11433         *trunc = FALSE;
11434         return offset;
11435 }
11436
11437 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11438    as described in 4.2.16.2
11439 */
11440 static int
11441 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11442     int offset, guint16 *bcp, gboolean *trunc)
11443 {
11444         guint8 name_len;
11445         guint16 data_len;
11446         /* EA size */
11447
11448         CHECK_BYTE_COUNT_SUBR(4);
11449         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11450         COUNT_BYTES_SUBR(4);
11451
11452         while (*bcp > 0) {
11453                 proto_item *item;
11454                 proto_tree *subtree;
11455                 int start_offset = offset;
11456                 guint8 *name;
11457
11458                 item = proto_tree_add_text(
11459                         tree, tvb, offset, 0, "Extended Attribute");
11460                 subtree = proto_item_add_subtree(item, ett_smb_ea);
11461
11462                 /* EA flags */
11463
11464                 CHECK_BYTE_COUNT_SUBR(1);
11465                 proto_tree_add_item(
11466                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
11467                 COUNT_BYTES_SUBR(1);
11468
11469                 /* EA name length */
11470
11471                 name_len = tvb_get_guint8(tvb, offset);
11472
11473                 CHECK_BYTE_COUNT_SUBR(1);
11474                 proto_tree_add_item(
11475                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
11476                 COUNT_BYTES_SUBR(1);
11477
11478                 /* EA data length */
11479
11480                 data_len = tvb_get_letohs(tvb, offset);
11481
11482                 CHECK_BYTE_COUNT_SUBR(2);
11483                 proto_tree_add_item(
11484                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
11485                 COUNT_BYTES_SUBR(2);
11486
11487                 /* EA name */
11488
11489                 name = tvb_get_ephemeral_string(tvb, offset, name_len);
11490                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
11491
11492                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
11493                 proto_tree_add_item(
11494                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
11495                         TRUE);
11496                 COUNT_BYTES_SUBR(name_len + 1);
11497
11498                 /* EA data */
11499
11500                 CHECK_BYTE_COUNT_SUBR(data_len);
11501                 proto_tree_add_item(
11502                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
11503                 COUNT_BYTES_SUBR(data_len);
11504
11505                 proto_item_set_len(item, offset - start_offset);
11506         }
11507
11508         *trunc = FALSE;
11509         return offset;
11510 }
11511
11512 /* this dissects the SMB_INFO_IS_NAME_VALID
11513    as described in 4.2.16.3
11514 */
11515 static int
11516 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11517     int offset, guint16 *bcp, gboolean *trunc)
11518 {
11519         smb_info_t *si = pinfo->private_data;
11520         int fn_len;
11521         const char *fn;
11522
11523         DISSECTOR_ASSERT(si);
11524
11525         /* file name */
11526         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11527         CHECK_STRING_SUBR(fn);
11528         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11529                 fn);
11530         COUNT_BYTES_SUBR(fn_len);
11531
11532         *trunc = FALSE;
11533         return offset;
11534 }
11535
11536 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11537    as described in 4.2.16.4
11538 */
11539 static int
11540 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11541     int offset, guint16 *bcp, gboolean *trunc)
11542 {
11543
11544         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11545         if (*trunc) {
11546           return offset;
11547         }
11548
11549         /* File Attributes */
11550         CHECK_BYTE_COUNT_SUBR(4);
11551         offset = dissect_file_attributes(tvb, tree, offset, 4);
11552         *bcp -= 4;
11553
11554         *trunc = FALSE;
11555         return offset;
11556 }
11557
11558 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11559    as described in 4.2.16.5
11560 */
11561 int
11562 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11563     int offset, guint16 *bcp, gboolean *trunc)
11564 {
11565         /* allocation size */
11566         CHECK_BYTE_COUNT_SUBR(8);
11567         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11568         COUNT_BYTES_SUBR(8);
11569
11570         /* end of file */
11571         CHECK_BYTE_COUNT_SUBR(8);
11572         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11573         COUNT_BYTES_SUBR(8);
11574
11575         /* number of links */
11576         CHECK_BYTE_COUNT_SUBR(4);
11577         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11578         COUNT_BYTES_SUBR(4);
11579
11580         /* delete pending */
11581         CHECK_BYTE_COUNT_SUBR(1);
11582         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11583         COUNT_BYTES_SUBR(1);
11584
11585         /* is directory */
11586         CHECK_BYTE_COUNT_SUBR(1);
11587         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11588         COUNT_BYTES_SUBR(1);
11589
11590         *trunc = FALSE;
11591         return offset;
11592 }
11593
11594 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
11595 */
11596 int
11597 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11598     int offset, guint16 *bcp, gboolean *trunc)
11599 {
11600         /* file id */
11601         CHECK_BYTE_COUNT_SUBR(8);
11602         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11603         COUNT_BYTES_SUBR(8);
11604
11605         *trunc = FALSE;
11606         return offset;
11607 }
11608
11609 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
11610 */
11611 int
11612 dissect_qfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11613     int offset, guint16 *bcp, gboolean *trunc)
11614 {
11615         /* file id */
11616         CHECK_BYTE_COUNT_SUBR(8);
11617         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, TRUE);
11618         COUNT_BYTES_SUBR(8);
11619
11620         *trunc = FALSE;
11621         return offset;
11622 }
11623
11624 /* this dissects the SMB_QUERY_FILE_MODE_INFO
11625 */
11626 int
11627 dissect_qfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11628     int offset, guint16 *bcp, gboolean *trunc)
11629 {
11630         /* mode */
11631         CHECK_BYTE_COUNT_SUBR(4);
11632         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, TRUE);
11633         COUNT_BYTES_SUBR(4);
11634
11635         *trunc = FALSE;
11636         return offset;
11637 }
11638
11639 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
11640 */
11641 int
11642 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11643     int offset, guint16 *bcp, gboolean *trunc)
11644 {
11645         /* alignment */
11646         CHECK_BYTE_COUNT_SUBR(4);
11647         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11648         COUNT_BYTES_SUBR(4);
11649
11650         *trunc = FALSE;
11651         return offset;
11652 }
11653
11654 /* this dissects the SMB_QUERY_FILE_EA_INFO
11655    as described in 4.2.16.6
11656 */
11657 int
11658 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11659     int offset, guint16 *bcp, gboolean *trunc)
11660 {
11661         /* ea length */
11662         CHECK_BYTE_COUNT_SUBR(4);
11663         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11664         COUNT_BYTES_SUBR(4);
11665
11666         *trunc = FALSE;
11667         return offset;
11668 }
11669
11670 /* this dissects the SMB_QUERY_FILE_ALLOCATION_INFO
11671 */
11672 int
11673 dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11674     int offset, guint16 *bcp, gboolean *trunc)
11675 {
11676         /* allocation size */
11677         CHECK_BYTE_COUNT_SUBR(8);
11678         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11679         COUNT_BYTES_SUBR(8);
11680
11681         *trunc = FALSE;
11682         return offset;
11683 }
11684
11685 /* this dissects the SMB_QUERY_FILE_ENDOFFILE_INFO
11686 */
11687 int
11688 dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11689     int offset, guint16 *bcp, gboolean *trunc)
11690 {
11691         /* end of file */
11692         CHECK_BYTE_COUNT_SUBR(8);
11693         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11694         COUNT_BYTES_SUBR(8);
11695
11696         *trunc = FALSE;
11697         return offset;
11698 }
11699
11700 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11701    as described in 4.2.16.7
11702    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11703    as described in 4.2.16.9
11704 */
11705 int
11706 dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11707     int offset, guint16 *bcp, gboolean *trunc)
11708 {
11709         smb_info_t *si = pinfo->private_data;
11710         int fn_len;
11711         const char *fn;
11712
11713         DISSECTOR_ASSERT(si);
11714
11715         /* file name len */
11716         CHECK_BYTE_COUNT_SUBR(4);
11717         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11718         COUNT_BYTES_SUBR(4);
11719
11720         /* file name */
11721         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11722         CHECK_STRING_SUBR(fn);
11723         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11724                 fn);
11725         COUNT_BYTES_SUBR(fn_len);
11726
11727         *trunc = FALSE;
11728         return offset;
11729 }
11730
11731 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11732    but not as described in 4.2.16.8 since CNIA spec is wrong
11733 */
11734 static int
11735 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11736     int offset, guint16 *bcp, gboolean *trunc)
11737 {
11738         smb_info_t *si;
11739         guint32 fn_len;
11740         const char *fn;
11741
11742         si = (smb_info_t *)pinfo->private_data;
11743
11744         DISSECTOR_ASSERT(si);
11745
11746         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11747         if (*trunc) {
11748           return offset;
11749         }
11750
11751         /* File Attributes */
11752         CHECK_BYTE_COUNT_SUBR(4);
11753         offset = dissect_file_attributes(tvb, tree, offset, 4);
11754         *bcp -= 4;
11755
11756         /* 4 pad bytes */
11757         offset+=4;
11758         *bcp -= 4;
11759
11760         /* allocation size */
11761         CHECK_BYTE_COUNT_SUBR(8);
11762         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11763         COUNT_BYTES_SUBR(8);
11764
11765         /* end of file */
11766         CHECK_BYTE_COUNT_SUBR(8);
11767         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11768         COUNT_BYTES_SUBR(8);
11769
11770         /* number of links */
11771         CHECK_BYTE_COUNT_SUBR(4);
11772         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11773         COUNT_BYTES_SUBR(4);
11774
11775         /* delete pending */
11776         CHECK_BYTE_COUNT_SUBR(1);
11777         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11778         COUNT_BYTES_SUBR(1);
11779
11780         /* is directory */
11781         CHECK_BYTE_COUNT_SUBR(1);
11782         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11783         COUNT_BYTES_SUBR(1);
11784
11785         /* 2 pad bytes */
11786         offset+=2;
11787         *bcp -= 2;
11788
11789         /* ea length */
11790         CHECK_BYTE_COUNT_SUBR(4);
11791         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11792         COUNT_BYTES_SUBR(4);
11793
11794         /* file name len */
11795         CHECK_BYTE_COUNT_SUBR(4);
11796         fn_len = (guint32)tvb_get_letohl(tvb, offset);
11797         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11798         COUNT_BYTES_SUBR(4);
11799
11800
11801         /* file name */
11802         CHECK_BYTE_COUNT_SUBR(fn_len);
11803         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
11804         if (fn != NULL) {
11805                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11806                         fn);
11807                 COUNT_BYTES_SUBR(fn_len);
11808         }
11809
11810
11811         if (*trunc)
11812                 return offset;
11813
11814         return offset;
11815 }
11816
11817 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11818    as described in 4.2.16.10
11819 */
11820 int
11821 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
11822     int offset, guint16 *bcp, gboolean *trunc, int unicode)
11823 {
11824         proto_item *item;
11825         proto_tree *tree;
11826         int old_offset;
11827         guint32 neo;
11828         int fn_len;
11829         const char *fn;
11830         int padcnt;
11831
11832
11833         for (;;) {
11834                 old_offset = offset;
11835
11836                 /* next entry offset */
11837                 CHECK_BYTE_COUNT_SUBR(4);
11838                 if(parent_tree){
11839                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11840                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11841                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11842                 } else {
11843                         item = NULL;
11844                         tree = NULL;
11845                 }
11846
11847                 neo = tvb_get_letohl(tvb, offset);
11848                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11849                 COUNT_BYTES_SUBR(4);
11850
11851                 /* stream name len */
11852                 CHECK_BYTE_COUNT_SUBR(4);
11853                 fn_len = tvb_get_letohl(tvb, offset);
11854                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11855                 COUNT_BYTES_SUBR(4);
11856
11857                 /* stream size */
11858                 CHECK_BYTE_COUNT_SUBR(8);
11859                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11860                 COUNT_BYTES_SUBR(8);
11861
11862                 /* allocation size */
11863                 CHECK_BYTE_COUNT_SUBR(8);
11864                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11865                 COUNT_BYTES_SUBR(8);
11866
11867                 /* stream name */
11868                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
11869                 CHECK_STRING_SUBR(fn);
11870                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11871                         fn);
11872                 COUNT_BYTES_SUBR(fn_len);
11873
11874                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
11875                 proto_item_set_len(item, offset-old_offset);
11876
11877                 if (neo == 0)
11878                         break;  /* no more structures */
11879
11880                 /* skip to next structure */
11881                 padcnt = (old_offset + neo) - offset;
11882                 if (padcnt < 0) {
11883                         /*
11884                          * XXX - this is bogus; flag it?
11885                          */
11886                         padcnt = 0;
11887                 }
11888                 if (padcnt != 0) {
11889                         CHECK_BYTE_COUNT_SUBR(padcnt);
11890                         COUNT_BYTES_SUBR(padcnt);
11891                 }
11892         }
11893
11894         *trunc = FALSE;
11895         return offset;
11896 }
11897
11898 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11899    as described in 4.2.16.11
11900 */
11901 int
11902 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11903     int offset, guint16 *bcp, gboolean *trunc)
11904 {
11905         /* compressed file size */
11906         CHECK_BYTE_COUNT_SUBR(8);
11907         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11908         COUNT_BYTES_SUBR(8);
11909
11910         /* compression format */
11911         CHECK_BYTE_COUNT_SUBR(2);
11912         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11913         COUNT_BYTES_SUBR(2);
11914
11915         /* compression unit shift */
11916         CHECK_BYTE_COUNT_SUBR(1);
11917         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11918         COUNT_BYTES_SUBR(1);
11919
11920         /* compression chunk shift */
11921         CHECK_BYTE_COUNT_SUBR(1);
11922         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11923         COUNT_BYTES_SUBR(1);
11924
11925         /* compression cluster shift */
11926         CHECK_BYTE_COUNT_SUBR(1);
11927         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11928         COUNT_BYTES_SUBR(1);
11929
11930         /* 3 reserved bytes */
11931         CHECK_BYTE_COUNT_SUBR(3);
11932         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11933         COUNT_BYTES_SUBR(3);
11934
11935         *trunc = FALSE;
11936         return offset;
11937 }
11938
11939 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11940
11941 static const value_string unix_file_type_vals[] = {
11942         { 0, "File" },
11943         { 1, "Directory" },
11944         { 2, "Symbolic link" },
11945         { 3, "Character device" },
11946         { 4, "Block device" },
11947         { 5, "FIFO" },
11948         { 6, "Socket" },
11949         { 0, NULL }
11950 };
11951
11952 static int
11953 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11954                   int offset, guint16 *bcp, gboolean *trunc)
11955 {
11956         /* End of file (file size) */
11957         CHECK_BYTE_COUNT_SUBR(8);
11958         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11959         COUNT_BYTES_SUBR(8);
11960
11961         /* Number of bytes */
11962         CHECK_BYTE_COUNT_SUBR(8);
11963         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11964         COUNT_BYTES_SUBR(8);
11965
11966         /* Last status change */
11967         CHECK_BYTE_COUNT_SUBR(8);
11968         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11969         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
11970
11971         /* Last access time */
11972         CHECK_BYTE_COUNT_SUBR(8);
11973         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11974         *bcp -= 8;
11975
11976         /* Last modification time */
11977         CHECK_BYTE_COUNT_SUBR(8);
11978         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11979         *bcp -= 8;
11980
11981         /* File owner uid */
11982         CHECK_BYTE_COUNT_SUBR(8);
11983         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11984         COUNT_BYTES_SUBR(8);
11985
11986         /* File group gid */
11987         CHECK_BYTE_COUNT_SUBR(8);
11988         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11989         COUNT_BYTES_SUBR(8);
11990
11991         /* File type */
11992         CHECK_BYTE_COUNT_SUBR(4);
11993         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11994         COUNT_BYTES_SUBR(4);
11995
11996         /* Major device number */
11997         CHECK_BYTE_COUNT_SUBR(8);
11998         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11999         COUNT_BYTES_SUBR(8);
12000
12001         /* Minor device number */
12002         CHECK_BYTE_COUNT_SUBR(8);
12003         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12004         COUNT_BYTES_SUBR(8);
12005
12006         /* Unique id */
12007         CHECK_BYTE_COUNT_SUBR(8);
12008         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12009         COUNT_BYTES_SUBR(8);
12010
12011         /* Permissions */
12012         CHECK_BYTE_COUNT_SUBR(8);
12013         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12014         COUNT_BYTES_SUBR(8);
12015
12016         /* Nlinks */
12017         CHECK_BYTE_COUNT_SUBR(8);
12018         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12019         COUNT_BYTES_SUBR(8);
12020
12021         /* Sometimes there is one extra byte in the data field which I
12022            guess could be padding, but we are only using 4 or 8 byte
12023            data types so this is a bit confusing. -tpot */
12024
12025         *trunc = FALSE;
12026         return offset;
12027 }
12028
12029 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
12030
12031 static int
12032 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12033                   int offset, guint16 *bcp, gboolean *trunc)
12034 {
12035         smb_info_t *si = pinfo->private_data;
12036         const char *fn;
12037         int fn_len;
12038
12039         DISSECTOR_ASSERT(si);
12040
12041         /* Link destination */
12042
12043         fn = get_unicode_or_ascii_string(
12044                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12045
12046         CHECK_STRING_SUBR(fn);
12047         proto_tree_add_string(
12048                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12049         COUNT_BYTES_SUBR(fn_len);
12050
12051         *trunc = FALSE;
12052         return offset;
12053 }
12054
12055 /* unix ACL
12056 */
12057 static int
12058 dissect_qpi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12059                   int offset, guint16 *bcp, gboolean *trunc)
12060 {
12061         guint16 version, num_file_aces, num_def_aces;
12062         static const int *perm_fields[] = {
12063                 &hf_smb_posix_ace_perm_read,
12064                 &hf_smb_posix_ace_perm_write,
12065                 &hf_smb_posix_ace_perm_execute,
12066                 NULL
12067         };
12068
12069         /* version */
12070         CHECK_BYTE_COUNT_SUBR(2);
12071         version = tvb_get_letohs(tvb, offset);
12072         proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, TRUE);
12073         COUNT_BYTES_SUBR(2);
12074
12075         /* num file acls */
12076         CHECK_BYTE_COUNT_SUBR(2);
12077         num_file_aces = tvb_get_letohs(tvb, offset);
12078         proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, TRUE);
12079         COUNT_BYTES_SUBR(2);
12080
12081         /* num default acls */
12082         CHECK_BYTE_COUNT_SUBR(2);
12083         num_def_aces = tvb_get_letohs(tvb, offset);
12084         proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, TRUE);
12085         COUNT_BYTES_SUBR(2);
12086
12087         while(num_file_aces--){
12088                 proto_item *it;
12089                 proto_tree *tr;
12090                 int old_offset = offset;
12091                 guint8 ace_type;
12092
12093                 it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
12094                 tr = proto_item_add_subtree(it, ett_smb_posic_ace);
12095
12096                 /* ace type */
12097                 CHECK_BYTE_COUNT_SUBR(1);
12098                 ace_type = tvb_get_guint8(tvb, offset);
12099                 proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, TRUE);
12100                 COUNT_BYTES_SUBR(1);
12101
12102                 CHECK_BYTE_COUNT_SUBR(1);
12103                 proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, FALSE);
12104                 COUNT_BYTES_SUBR(1);
12105
12106                 switch(ace_type){
12107                 case POSIX_ACE_TYPE_USER_OBJ:
12108                         CHECK_BYTE_COUNT_SUBR(4);
12109                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, TRUE);
12110                         COUNT_BYTES_SUBR(4);
12111
12112                         CHECK_BYTE_COUNT_SUBR(4);
12113                         /* 4 reserved bytes */
12114                         COUNT_BYTES_SUBR(4);
12115                         break;
12116                 case POSIX_ACE_TYPE_GROUP_OBJ:
12117                         CHECK_BYTE_COUNT_SUBR(4);
12118                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, TRUE);
12119                         COUNT_BYTES_SUBR(4);
12120
12121                         CHECK_BYTE_COUNT_SUBR(4);
12122                         /* 4 reserved bytes */
12123                         COUNT_BYTES_SUBR(4);
12124                         break;
12125
12126                 case POSIX_ACE_TYPE_MASK:
12127                 case POSIX_ACE_TYPE_OTHER:
12128                         CHECK_BYTE_COUNT_SUBR(8);
12129                         /* 8 reserved bytes */
12130                         COUNT_BYTES_SUBR(8);
12131                         break;
12132
12133                 case POSIX_ACE_TYPE_USER:
12134                         CHECK_BYTE_COUNT_SUBR(4);
12135                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, TRUE);
12136                         COUNT_BYTES_SUBR(4);
12137
12138                         CHECK_BYTE_COUNT_SUBR(4);
12139                         /* 4 reserved bytes */
12140                         COUNT_BYTES_SUBR(4);
12141                         break;
12142
12143                 case POSIX_ACE_TYPE_GROUP:
12144                         CHECK_BYTE_COUNT_SUBR(4);
12145                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, TRUE);
12146                         COUNT_BYTES_SUBR(4);
12147
12148                         CHECK_BYTE_COUNT_SUBR(4);
12149                         /* 4 reserved bytes */
12150                         COUNT_BYTES_SUBR(4);
12151                         break;
12152                 default:
12153                         proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
12154                         CHECK_BYTE_COUNT_SUBR(8);
12155                         /* skip 8 bytes */
12156                         COUNT_BYTES_SUBR(8);
12157                 }
12158
12159                 proto_item_set_len(it, offset-old_offset);
12160         }
12161
12162         return offset;
12163 }
12164
12165 static int
12166 dissect_qpi_unix_xattr(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12167                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12168 {
12169         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12170
12171         return offset;
12172 }
12173
12174 static int
12175 dissect_qpi_unix_attr_flags(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12176                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12177 {
12178         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12179
12180         return offset;
12181 }
12182
12183 static int
12184 dissect_qpi_unix_permissions(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12185                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12186 {
12187         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12188
12189         return offset;
12190 }
12191
12192 static int
12193 dissect_qpi_unix_lock(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12194                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12195 {
12196         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12197
12198         return offset;
12199 }
12200
12201 static int
12202 dissect_qpi_unix_open(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12203                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12204 {
12205         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12206
12207         return offset;
12208 }
12209
12210 static int
12211 dissect_qpi_unix_unlink(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12212                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12213 {
12214         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12215
12216         return offset;
12217 }
12218
12219 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
12220 */
12221 int
12222 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
12223     packet_info *pinfo, proto_tree *tree,
12224     int offset, guint16 *bcp, gboolean *trunc)
12225 {
12226
12227         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12228         if (*trunc) {
12229           return offset;
12230         }
12231
12232         /* allocation size */
12233         CHECK_BYTE_COUNT_SUBR(8);
12234         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12235         COUNT_BYTES_SUBR(8);
12236
12237         /* end of file */
12238         CHECK_BYTE_COUNT_SUBR(8);
12239         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12240         COUNT_BYTES_SUBR(8);
12241
12242         /* File Attributes */
12243         CHECK_BYTE_COUNT_SUBR(4);
12244         offset = dissect_file_attributes(tvb, tree, offset, 4);
12245         *bcp -= 4;
12246
12247         /* Unknown, possibly count of network accessors ... */
12248         CHECK_BYTE_COUNT_SUBR(4);
12249         proto_tree_add_item(tree, hf_smb_network_unknown, tvb, offset, 4, TRUE);
12250         COUNT_BYTES_SUBR(4);
12251
12252         *trunc = FALSE;
12253         return offset;
12254 }
12255
12256 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
12257 */
12258 int
12259 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
12260     packet_info *pinfo _U_, proto_tree *tree,
12261     int offset, guint16 *bcp, gboolean *trunc)
12262 {
12263         /* attribute */
12264         CHECK_BYTE_COUNT_SUBR(4);
12265         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, TRUE);
12266         COUNT_BYTES_SUBR(4);
12267
12268         /* reparse tag */
12269         CHECK_BYTE_COUNT_SUBR(4);
12270         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, TRUE);
12271         COUNT_BYTES_SUBR(4);
12272
12273         *trunc = FALSE;
12274         return offset;
12275 }
12276
12277 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
12278    as described in 4.2.19.2
12279 */
12280 static int
12281 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12282     int offset, guint16 *bcp, gboolean *trunc)
12283 {
12284         /* marked for deletion? */
12285         CHECK_BYTE_COUNT_SUBR(1);
12286         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
12287         COUNT_BYTES_SUBR(1);
12288
12289         *trunc = FALSE;
12290         return offset;
12291 }
12292
12293 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
12294    as described in 4.2.19.3
12295 */
12296 static int
12297 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12298     int offset, guint16 *bcp, gboolean *trunc)
12299 {
12300         /* file allocation size */
12301         CHECK_BYTE_COUNT_SUBR(8);
12302         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12303         COUNT_BYTES_SUBR(8);
12304
12305         *trunc = FALSE;
12306         return offset;
12307 }
12308
12309 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
12310    as described in 4.2.19.4
12311 */
12312 static int
12313 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12314     int offset, guint16 *bcp, gboolean *trunc)
12315 {
12316         /* file end of file offset */
12317         CHECK_BYTE_COUNT_SUBR(8);
12318         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12319         COUNT_BYTES_SUBR(8);
12320
12321         *trunc = FALSE;
12322         return offset;
12323 }
12324
12325 /* Set File Rename Info */
12326
12327 static const true_false_string tfs_smb_replace = {
12328         "Remove target file if it exists",
12329         "Do NOT remove target file if it exists",
12330 };
12331
12332 static int
12333 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12334                     int offset, guint16 *bcp, gboolean *trunc)
12335 {
12336         smb_info_t *si = pinfo->private_data;
12337         const char *fn;
12338         guint32 target_name_len;
12339         int fn_len;
12340
12341         DISSECTOR_ASSERT(si);
12342
12343         /* Replace flag */
12344         CHECK_BYTE_COUNT_SUBR(4);
12345         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
12346         COUNT_BYTES_SUBR(4);
12347
12348         /* Root directory handle */
12349         CHECK_BYTE_COUNT_SUBR(4);
12350         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
12351         COUNT_BYTES_SUBR(4);
12352
12353         /* Target name length */
12354         CHECK_BYTE_COUNT_SUBR(4);
12355         target_name_len = tvb_get_letohl(tvb, offset);
12356         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
12357         COUNT_BYTES_SUBR(4);
12358
12359         /* Target name */
12360         fn_len = target_name_len;
12361         fn = get_unicode_or_ascii_string(
12362                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12363
12364         CHECK_STRING_SUBR(fn);
12365         proto_tree_add_string(
12366                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
12367         COUNT_BYTES_SUBR(fn_len);
12368
12369         *trunc = FALSE;
12370         return offset;
12371 }
12372
12373 static int
12374 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12375                     int offset, guint16 *bcp, gboolean *trunc)
12376 {
12377         smb_info_t *si = pinfo->private_data;
12378 /*      const char *fn;*/
12379 /*      guint32 target_name_len;*/
12380 /*      int fn_len;*/
12381
12382         DISSECTOR_ASSERT(si);
12383
12384         /* Disposition flags */
12385         CHECK_BYTE_COUNT_SUBR(1);
12386         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, TRUE);
12387         COUNT_BYTES_SUBR(1);
12388
12389         *trunc = FALSE;
12390         return offset;
12391 }
12392
12393 int
12394 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12395                     int offset, guint16 *bcp, gboolean *trunc)
12396 {
12397         smb_info_t *si = pinfo->private_data;
12398
12399         DISSECTOR_ASSERT(si);
12400
12401         /* pipe info flag */
12402         CHECK_BYTE_COUNT_SUBR(1);
12403         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, TRUE);
12404         COUNT_BYTES_SUBR(1);
12405
12406         *trunc = FALSE;
12407         return offset;
12408 }
12409
12410 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
12411   TRANS2_QUERY_FILE_INFORMATION*/
12412 static int
12413 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12414     int offset, guint16 *bcp)
12415 {
12416         smb_info_t *si;
12417         gboolean trunc;
12418
12419         if(!*bcp){
12420                 return offset;
12421         }
12422
12423         si = (smb_info_t *)pinfo->private_data;
12424         DISSECTOR_ASSERT(si);
12425
12426         switch(si->info_level){
12427         case 1:         /*Info Standard*/
12428                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12429                     &trunc);
12430                 break;
12431
12432         case 2:         /*Info Query EA Size*/
12433                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12434                     &trunc);
12435                 break;
12436         case 3:         /*Info Query EAs From List*/
12437         case 4:         /*Info Query All EAs*/
12438                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12439                     &trunc);
12440                 break;
12441         case 6:         /*Info Is Name Valid*/
12442                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
12443                     &trunc);
12444                 break;
12445         case 0x0101:    /*Query File Basic Info*/
12446         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12447                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12448                     &trunc);
12449                 break;
12450         case 0x0102:    /*Query File Standard Info*/
12451         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
12452                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
12453                     &trunc);
12454                 break;
12455         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
12456                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
12457                     &trunc);
12458                 break;
12459         case 0x0103:    /*Query File EA Info*/
12460         case 1007:      /* SMB_FILE_EA_INFORMATION */
12461                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
12462                     &trunc);
12463                 break;
12464         case 0x0104:    /*Query File Name Info*/
12465         case 1009:      /* SMB_FILE_NAME_INFORMATION */
12466                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12467                     &trunc);
12468                 break;
12469         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
12470                 offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
12471                     &trunc);
12472                 break;
12473         case 1016:      /* SMB_FILE_MODE_INFORMATION */
12474                 offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
12475                     &trunc);
12476                 break;
12477         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
12478                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
12479                     &trunc);
12480                 break;
12481         case 0x0107:    /*Query File All Info*/
12482         case 1018:      /* SMB_FILE_ALL_INFORMATION */
12483                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
12484                     &trunc);
12485                 break;
12486         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
12487                 offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
12488                     &trunc);
12489                 break;
12490         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
12491                 offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
12492                     &trunc);
12493                 break;
12494         case 0x0108:    /*Query File Alt File Info*/
12495         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
12496                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12497                     &trunc);
12498                 break;
12499         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
12500                 si->unicode = TRUE;
12501         case 0x0109:    /*Query File Stream Info*/
12502                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
12503                     &trunc, si->unicode);
12504                 break;
12505         case 0x010b:    /*Query File Compression Info*/
12506         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
12507                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
12508                     &trunc);
12509                 break;
12510         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
12511                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12512                 break;
12513         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
12514                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12515                 break;
12516         case 0x0200:    /* Query File Unix Basic*/
12517                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12518                                            &trunc);
12519                 break;
12520         case 0x0201:    /* Query File Unix Link*/
12521                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12522                                            &trunc);
12523                 break;
12524         case 0x0202:    /* Query File Unix HardLink*/
12525                 /* XXX add this from the SNIA doc */
12526                 break;
12527         case 0x0204:    /* Query File Unix ACL*/
12528                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12529                                            &trunc);
12530                 break;
12531         case 0x0205:    /* Query File Unix XATTR*/
12532                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12533                                            &trunc);
12534                 break;
12535         case 0x0206:    /* Query File Unix Attr Flags*/
12536                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12537                                            &trunc);
12538                 break;
12539         case 0x0207:    /* Query File Unix Permissions*/
12540                 offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
12541                                            &trunc);
12542                 break;
12543         case 0x0208:    /* Query File Unix Lock*/
12544                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12545                                            &trunc);
12546                 break;
12547         }
12548
12549         return offset;
12550 }
12551
12552 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
12553   TRANS2_SET_FILE_INFORMATION*/
12554 static int
12555 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12556     int offset, guint16 *bcp)
12557 {
12558         smb_info_t *si;
12559         gboolean trunc;
12560
12561         if(!*bcp){
12562                 return offset;
12563         }
12564
12565         si = (smb_info_t *)pinfo->private_data;
12566         DISSECTOR_ASSERT(si);
12567
12568         switch(si->info_level){
12569         case 1:         /*Info Standard*/
12570                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12571                     &trunc);
12572                 break;
12573         case 2:         /*Info Query EA Size*/
12574                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12575                     &trunc);
12576                 break;
12577         case 4:         /*Info Query All EAs*/
12578                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12579                     &trunc);
12580                 break;
12581         case 0x0101:    /*Set File Basic Info*/
12582         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12583                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12584                     &trunc);
12585                 break;
12586         case 0x0102:    /*Set File Disposition Info*/
12587                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
12588                     &trunc);
12589                 break;
12590         case 0x0103:    /*Set File Allocation Info*/
12591                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
12592                     &trunc);
12593                 break;
12594         case 0x0104:    /*Set End Of File Info*/
12595                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
12596                     &trunc);
12597                 break;
12598         case 0x0200:    /*Set File Unix Basic.  Same as query. */
12599                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12600                     &trunc);
12601                 break;
12602         case 0x0201:    /*Set File Unix Link.  Same as query. */
12603                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12604                     &trunc);
12605                 break;
12606         case 0x0202:    /*Set File Unix HardLink.  Same as link query. */
12607                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12608                     &trunc);
12609                 break;
12610         case 0x0204:    /* Set File Unix ACL*/
12611                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12612                                            &trunc);
12613                 break;
12614         case 0x0205:    /* Set File Unix XATTR*/
12615                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12616                                            &trunc);
12617                 break;
12618         case 0x0206:    /* Set File Unix Attr Flags*/
12619                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12620                                            &trunc);
12621                 break;
12622         case 0x0208:    /* Set File Unix Lock*/
12623                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12624                                            &trunc);
12625                 break;
12626         case 0x0209:    /* Set File Unix Open*/
12627                 offset = dissect_qpi_unix_open(tvb, pinfo, tree, offset, bcp,
12628                                            &trunc);
12629                 break;
12630         case 0x020a:    /* Set File Unix Unlink*/
12631                 offset = dissect_qpi_unix_unlink(tvb, pinfo, tree, offset, bcp,
12632                                            &trunc);
12633                 break;
12634         case 1010:      /* Set File Rename */
12635                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
12636                     &trunc);
12637                 break;
12638         case 1013: /* Set Disposition Information */
12639                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
12640                     &trunc);
12641                 break;
12642         case 1023: /* Set Pipe Info */
12643                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
12644                     &trunc);
12645                 break;
12646         case 1014:
12647         case 1016:
12648         case 1019:
12649         case 1020:
12650         case 1025:
12651         case 1029:
12652         case 1032:
12653         case 1039:
12654         case 1040:
12655                 /* XXX: TODO, extra levels discovered by tridge */
12656                 break;
12657         }
12658
12659         return offset;
12660 }
12661
12662
12663 static const true_false_string tfs_quota_flags_deny_disk = {
12664         "DENY DISK SPACE for users exceeding quota limit",
12665         "Do NOT deny disk space for users exceeding quota limit"
12666 };
12667 static const true_false_string tfs_quota_flags_log_limit = {
12668         "LOG EVENT when a user exceeds their QUOTA LIMIT",
12669         "Do NOT log event when a user exceeds their quota limit"
12670 };
12671 static const true_false_string tfs_quota_flags_log_warning = {
12672         "LOG EVENT when a user exceeds their WARNING LEVEL",
12673         "Do NOT log event when a user exceeds their warning level"
12674 };
12675 static const true_false_string tfs_quota_flags_enabled = {
12676         "Quotas are ENABLED of this fs",
12677         "Quotas are NOT enabled on this fs"
12678 };
12679 static void
12680 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12681 {
12682         guint8 mask;
12683         proto_item *item;
12684         proto_tree *tree;
12685
12686         mask = tvb_get_guint8(tvb, offset);
12687
12688         if(parent_tree){
12689                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
12690                         "Quota Flags: 0x%02x %s", mask,
12691                         mask?"Enabled":"Disabled");
12692                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
12693
12694                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
12695                         tvb, offset, 1, mask);
12696                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
12697                         tvb, offset, 1, mask);
12698                 proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
12699                         tvb, offset, 1, mask);
12700
12701                 if(mask && (!(mask&0x01))){
12702                         proto_item *hidden_item;
12703                         hidden_item = proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12704                                 tvb, offset, 1, 0x01);
12705                         PROTO_ITEM_SET_HIDDEN(hidden_item);
12706                 } else {
12707                         proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12708                                 tvb, offset, 1, mask);
12709                 }
12710         }
12711
12712 }
12713
12714 int
12715 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
12716 {
12717         /* first 24 bytes are unknown */
12718         CHECK_BYTE_COUNT_TRANS_SUBR(24);
12719         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12720                     offset, 24, TRUE);
12721         COUNT_BYTES_TRANS_SUBR(24);
12722
12723         /* number of bytes for quota warning */
12724         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12725         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
12726         COUNT_BYTES_TRANS_SUBR(8);
12727
12728         /* number of bytes for quota limit */
12729         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12730         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
12731         COUNT_BYTES_TRANS_SUBR(8);
12732
12733         /* one byte of quota flags */
12734         CHECK_BYTE_COUNT_TRANS_SUBR(1);
12735         dissect_quota_flags(tvb, tree, offset);
12736         COUNT_BYTES_TRANS_SUBR(1);
12737
12738         /* these 7 bytes are unknown */
12739         CHECK_BYTE_COUNT_TRANS_SUBR(7);
12740         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12741                     offset, 7, TRUE);
12742         COUNT_BYTES_TRANS_SUBR(7);
12743
12744         return offset;
12745 }
12746
12747 static int
12748 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
12749     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
12750 {
12751         proto_item *item = NULL;
12752         proto_tree *tree = NULL;
12753         smb_info_t *si;
12754
12755         si = (smb_info_t *)pinfo->private_data;
12756         DISSECTOR_ASSERT(si);
12757
12758         if(parent_tree){
12759                 tvb_ensure_bytes_exist(tvb, offset, dc);
12760                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12761                                 "%s Data",
12762                                 val_to_str(subcmd, trans2_cmd_vals,
12763                                                 "Unknown (0x%02x)"));
12764                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12765         }
12766
12767         switch(subcmd){
12768         case 0x00:      /*TRANS2_OPEN2*/
12769                 /* XXX dont know how to decode FEAList */
12770                 break;
12771         case 0x01:      /*TRANS2_FIND_FIRST2*/
12772                 /* XXX dont know how to decode FEAList */
12773                 break;
12774         case 0x02:      /*TRANS2_FIND_NEXT2*/
12775                 /* XXX dont know how to decode FEAList */
12776                 break;
12777         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12778                 /* no data field in this request */
12779                 break;
12780         case 0x04:      /* TRANS2_SET_QUOTA */
12781                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
12782                 break;
12783         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12784                 /* no data field in this request */
12785                 /*
12786                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12787                  * Extensions Version 3.0, Document Version 1.11,
12788                  * July 19, 1990" says there may be "Additional
12789                  * FileInfoLevel dependent information" here.
12790                  *
12791                  * Was that just a cut-and-pasteo?
12792                  * TRANS2_SET_PATH_INFORMATION *does* have that information
12793                  * here.
12794                  */
12795                 break;
12796         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12797                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12798                 break;
12799         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12800                 /* no data field in this request */
12801                 /*
12802                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12803                  * Extensions Version 3.0, Document Version 1.11,
12804                  * July 19, 1990" says there may be "Additional
12805                  * FileInfoLevel dependent information" here.
12806                  *
12807                  * Was that just a cut-and-pasteo?
12808                  * TRANS2_SET_FILE_INFORMATION *does* have that information
12809                  * here.
12810                  */
12811                 break;
12812         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12813                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12814                 break;
12815         case 0x09:      /*TRANS2_FSCTL*/
12816                 /*XXX dont know how to decode this yet */
12817
12818                 /*
12819                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12820                  * Extensions Version 3.0, Document Version 1.11,
12821                  * July 19, 1990" says this this contains a
12822                  * "File system specific data block".  (That means we
12823                  * may not be able to dissect it in any case.)
12824                  */
12825                 break;
12826         case 0x0a:      /*TRANS2_IOCTL2*/
12827                 /*XXX dont know how to decode this yet */
12828
12829                 /*
12830                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12831                  * Extensions Version 3.0, Document Version 1.11,
12832                  * July 19, 1990" says this this contains a
12833                  * "Device/function specific data block".  (That
12834                  * means we may not be able to dissect it in any case.)
12835                  */
12836                 break;
12837         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12838                 /*XXX dont know how to decode this yet */
12839
12840                 /*
12841                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12842                  * Extensions Version 3.0, Document Version 1.11,
12843                  * July 19, 1990" says this this contains "additional
12844                  * level dependent match data".
12845                  */
12846                 break;
12847         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12848                 /*XXX dont know how to decode this yet */
12849
12850                 /*
12851                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12852                  * Extensions Version 3.0, Document Version 1.11,
12853                  * July 19, 1990" says this this contains "additional
12854                  * level dependent monitor information".
12855                  */
12856                 break;
12857         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12858                 /* XXX optional FEAList, unknown what FEAList looks like*/
12859                 break;
12860         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12861                 /*XXX dont know how to decode this yet */
12862                 break;
12863         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12864                 /* no data field in this request */
12865                 break;
12866         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12867                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
12868                 break;
12869         }
12870
12871         /* ooops there were data we didnt know how to process */
12872         if(dc != 0){
12873                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12874                 offset += dc;
12875         }
12876
12877         return offset;
12878 }
12879
12880
12881 static void
12882 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
12883     proto_tree *tree)
12884 {
12885         int i;
12886         int offset;
12887         guint length;
12888
12889         /*
12890          * Show the setup words.
12891          */
12892         if (s_tvb != NULL) {
12893                 length = tvb_reported_length(s_tvb);
12894                 for (i = 0, offset = 0; length >= 2;
12895                     i++, offset += 2, length -= 2) {
12896                         /*
12897                          * XXX - add a setup word filterable field?
12898                          */
12899                         proto_tree_add_text(tree, s_tvb, offset, 2,
12900                             "Setup Word %d: 0x%04x", i,
12901                             tvb_get_letohs(s_tvb, offset));
12902                 }
12903         }
12904
12905         /*
12906          * Show the parameters, if any.
12907          */
12908         if (p_tvb != NULL) {
12909                 length = tvb_reported_length(p_tvb);
12910                 if (length != 0) {
12911                         proto_tree_add_text(tree, p_tvb, 0, length,
12912                             "Parameters: %s",
12913                             tvb_bytes_to_str(p_tvb, 0, length));
12914                 }
12915         }
12916
12917         /*
12918          * Show the data, if any.
12919          */
12920         if (d_tvb != NULL) {
12921                 length = tvb_reported_length(d_tvb);
12922                 if (length != 0) {
12923                         proto_tree_add_text(tree, d_tvb, 0, length,
12924                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
12925                 }
12926         }
12927 }
12928
12929 /* This routine handles the following 4 calls
12930    Transaction  0x25
12931    Transaction Secondary 0x26
12932    Transaction2 0x32
12933    Transaction2 Secondary 0x33
12934 */
12935 static int
12936 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12937 {
12938         guint8 wc, sc=0;
12939         int so=offset;
12940         int sl=0;
12941         int spo=offset;
12942         int spc=0;
12943         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
12944         int subcmd = -1;
12945         guint32 to;
12946         int an_len;
12947         const char *an = NULL;
12948         smb_info_t *si;
12949         smb_transact2_info_t *t2i;
12950         smb_transact_info_t *tri;
12951         guint16 bc;
12952         int padcnt;
12953         gboolean dissected_trans;
12954
12955         si = (smb_info_t *)pinfo->private_data;
12956         DISSECTOR_ASSERT(si);
12957
12958         WORD_COUNT;
12959
12960         if(wc==8){
12961                 /*secondary client request*/
12962
12963                 /* total param count, only a 16bit integer here*/
12964                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12965                 offset += 2;
12966
12967                 /* total data count , only 16bit integer here*/
12968                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12969                 offset += 2;
12970
12971                 /* param count */
12972                 pc = tvb_get_letohs(tvb, offset);
12973                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12974                 offset += 2;
12975
12976                 /* param offset */
12977                 po = tvb_get_letohs(tvb, offset);
12978                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12979                 offset += 2;
12980
12981                 /* param disp */
12982                 pd = tvb_get_letohs(tvb, offset);
12983                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12984                 offset += 2;
12985
12986                 /* data count */
12987                 dc = tvb_get_letohs(tvb, offset);
12988                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12989                 offset += 2;
12990
12991                 /* data offset */
12992                 od = tvb_get_letohs(tvb, offset);
12993                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12994                 offset += 2;
12995
12996                 /* data disp */
12997                 dd = tvb_get_letohs(tvb, offset);
12998                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12999                 offset += 2;
13000
13001                 if(si->cmd==SMB_COM_TRANSACTION2){
13002                         guint16 fid;
13003
13004                         /* fid */
13005                         fid = tvb_get_letohs(tvb, offset);
13006                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
13007
13008                         offset += 2;
13009                 }
13010
13011                 /* There are no setup words. */
13012                 so = offset;
13013                 sc = 0;
13014                 sl = 0;
13015         } else {
13016                 /* it is not a secondary request */
13017
13018                 /* total param count , only a 16 bit integer here*/
13019                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13020                 offset += 2;
13021
13022                 /* total data count , only 16bit integer here*/
13023                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13024                 offset += 2;
13025
13026                 /* max param count , only 16bit integer here*/
13027                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13028                 offset += 2;
13029
13030                 /* max data count, only 16bit integer here*/
13031                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13032                 offset += 2;
13033
13034                 /* max setup count, only 16bit integer here*/
13035                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13036                 offset += 1;
13037
13038                 /* reserved byte */
13039                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13040                 offset += 1;
13041
13042                 /* transaction flags */
13043                 tf = dissect_transaction_flags(tvb, tree, offset);
13044                 offset += 2;
13045
13046                 /* timeout */
13047                 to = tvb_get_letohl(tvb, offset);
13048                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
13049                 offset += 4;
13050
13051                 /* 2 reserved bytes */
13052                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13053                 offset += 2;
13054
13055                 /* param count */
13056                 pc = tvb_get_letohs(tvb, offset);
13057                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13058                 offset += 2;
13059
13060                 /* param offset */
13061                 po = tvb_get_letohs(tvb, offset);
13062                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13063                 offset += 2;
13064
13065                 /* param displacement is zero here */
13066                 pd = 0;
13067
13068                 /* data count */
13069                 dc = tvb_get_letohs(tvb, offset);
13070                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13071                 offset += 2;
13072
13073                 /* data offset */
13074                 od = tvb_get_letohs(tvb, offset);
13075                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13076                 offset += 2;
13077
13078                 /* data displacement is zero here */
13079                 dd = 0;
13080
13081                 /* setup count */
13082                 sc = tvb_get_guint8(tvb, offset);
13083                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13084                 offset += 1;
13085
13086                 /* reserved byte */
13087                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13088                 offset += 1;
13089
13090                 /* this is where the setup bytes, if any start */
13091                 so = offset;
13092                 sl = sc*2;
13093
13094                 /* if there were any setup bytes, decode them */
13095                 if(sc){
13096                         switch(si->cmd){
13097
13098                         case SMB_COM_TRANSACTION2:
13099                                 /* TRANSACTION2 only has one setup word and
13100                                    that is the subcommand code.
13101
13102                                    XXX - except for TRANS2_FSCTL
13103                                    and TRANS2_IOCTL. */
13104                                 subcmd = tvb_get_letohs(tvb, offset);
13105                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
13106                                     tvb, offset, 2, subcmd);
13107                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13108                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13109                                             val_to_str(subcmd, trans2_cmd_vals,
13110                                                 "Unknown (0x%02x)"));
13111                                 }
13112                                 if (!si->unidir) {
13113                                         if(!pinfo->fd->flags.visited && si->sip){
13114                                                 /*
13115                                                  * Allocate a new
13116                                                  * smb_transact2_info_t
13117                                                  * structure.
13118                                                  */
13119                                                 t2i = se_alloc(sizeof(smb_transact2_info_t));
13120                                                 t2i->subcmd = subcmd;
13121                                                 t2i->info_level = -1;
13122                                                 t2i->resume_keys = FALSE;
13123                                                 t2i->name = NULL;
13124                                                 si->sip->extra_info = t2i;
13125                                                 si->sip->extra_info_type = SMB_EI_T2I;
13126                                         }
13127                                 }
13128
13129                                 /*
13130                                  * XXX - process TRANS2_FSCTL and
13131                                  * TRANS2_IOCTL setup words here.
13132                                  */
13133                                 break;
13134
13135                         case SMB_COM_TRANSACTION:
13136                                 /* TRANSACTION setup words processed below */
13137                                 break;
13138                         }
13139
13140                         offset += sl;
13141                 }
13142         }
13143
13144         BYTE_COUNT;
13145
13146         if(wc!=8){
13147                 /* primary request */
13148                 /* name is NULL if transaction2 */
13149                 if(si->cmd == SMB_COM_TRANSACTION){
13150                         /* Transaction Name */
13151                         an = get_unicode_or_ascii_string(tvb, &offset,
13152                                 si->unicode, &an_len, FALSE, FALSE, &bc);
13153                         if (an == NULL)
13154                                 goto endofcommand;
13155                         tvb_ensure_bytes_exist(tvb, offset, an_len);
13156                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
13157                                 offset, an_len, an);
13158                         COUNT_BYTES(an_len);
13159                 }
13160         }
13161
13162         /*
13163          * The pipe or mailslot arguments for Transaction start with
13164          * the first setup word (or where the first setup word would
13165          * be if there were any setup words), and run to the current
13166          * offset (which could mean that there aren't any).
13167          */
13168         spo = so;
13169         spc = offset - spo;
13170
13171         /* parameters */
13172         if(po>offset){
13173                 /* We have some initial padding bytes.
13174                 */
13175                 padcnt = po-offset;
13176                 if (padcnt > bc)
13177                         padcnt = bc;
13178                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13179                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13180                 COUNT_BYTES(padcnt);
13181         }
13182         if(pc){
13183                 CHECK_BYTE_COUNT(pc);
13184                 switch(si->cmd) {
13185
13186                 case SMB_COM_TRANSACTION2:
13187                         /* TRANSACTION2 parameters*/
13188                         offset = dissect_transaction2_request_parameters(tvb,
13189                             pinfo, tree, offset, subcmd, pc);
13190                         bc -= pc;
13191                         break;
13192
13193                 case SMB_COM_TRANSACTION:
13194                         /* TRANSACTION parameters processed below */
13195                         COUNT_BYTES(pc);
13196                         break;
13197                 }
13198         }
13199
13200         /* data */
13201         if(od>offset){
13202                 /* We have some initial padding bytes.
13203                 */
13204                 padcnt = od-offset;
13205                 if (padcnt > bc)
13206                         padcnt = bc;
13207                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13208                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13209                 COUNT_BYTES(padcnt);
13210         }
13211         if(dc){
13212                 CHECK_BYTE_COUNT(dc);
13213                 switch(si->cmd){
13214
13215                 case SMB_COM_TRANSACTION2:
13216                         /* TRANSACTION2 data*/
13217                         offset = dissect_transaction2_request_data(tvb, pinfo,
13218                             tree, offset, subcmd, dc);
13219                         bc -= dc;
13220                         break;
13221
13222                 case SMB_COM_TRANSACTION:
13223                         /* TRANSACTION data processed below */
13224                         COUNT_BYTES(dc);
13225                         break;
13226                 }
13227         }
13228
13229         /*TRANSACTION request parameters */
13230         if(si->cmd==SMB_COM_TRANSACTION){
13231                 /*XXX replace this block with a function and use that one
13232                      for both requests/responses*/
13233                 if(dd==0){
13234                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
13235                         tvbuff_t *sp_tvb, *pd_tvb;
13236
13237                         if(pc>0){
13238                                 if(pc>tvb_length_remaining(tvb, po)){
13239                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
13240                                 } else {
13241                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
13242                                 }
13243                         } else {
13244                                 p_tvb = NULL;
13245                         }
13246                         if(dc>0){
13247                                 if(dc>tvb_length_remaining(tvb, od)){
13248                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
13249                                 } else {
13250                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
13251                                 }
13252                         } else {
13253                                 d_tvb = NULL;
13254                         }
13255                         if(sl){
13256                                 if(sl>tvb_length_remaining(tvb, so)){
13257                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
13258                                 } else {
13259                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
13260                                 }
13261                         } else {
13262                                 s_tvb = NULL;
13263                         }
13264
13265                         if (!si->unidir) {
13266                                 if(!pinfo->fd->flags.visited && si->sip){
13267                                         /*
13268                                          * Allocate a new smb_transact_info_t
13269                                          * structure.
13270                                          */
13271                                         tri = se_alloc(sizeof(smb_transact_info_t));
13272                                         tri->subcmd = -1;
13273                                         tri->trans_subcmd = -1;
13274                                         tri->function = -1;
13275                                         tri->fid = -1;
13276                                         tri->lanman_cmd = 0;
13277                                         tri->param_descrip = NULL;
13278                                         tri->data_descrip = NULL;
13279                                         tri->aux_data_descrip = NULL;
13280                                         tri->info_level = -1;
13281                                         si->sip->extra_info = tri;
13282                                         si->sip->extra_info_type = SMB_EI_TRI;
13283                                 } else {
13284                                         /*
13285                                          * We already filled the structure
13286                                          * in; don't bother doing so again.
13287                                          */
13288                                         tri = NULL;
13289                                 }
13290                         } else {
13291                                 /*
13292                                  * This is a unidirectional message, for
13293                                  * which there will be no reply; don't
13294                                  * bother allocating an "smb_transact_info_t"
13295                                  * structure for it.
13296                                  */
13297                                 tri = NULL;
13298                         }
13299                         dissected_trans = FALSE;
13300                         if (an == NULL)
13301                                 goto endofcommand;
13302                         if(strncmp("\\PIPE\\", an, 6) == 0){
13303                                 if (tri != NULL)
13304                                         tri->subcmd=TRANSACTION_PIPE;
13305
13306                                 /*
13307                                  * A tvbuff containing the setup words and
13308                                  * the pipe path.
13309                                  */
13310                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13311
13312                                 /*
13313                                  * A tvbuff containing the parameters and the
13314                                  * data.
13315                                  */
13316                                 pd_tvb = tvb_new_subset_remaining(tvb, po);
13317
13318                                 dissected_trans = dissect_pipe_smb(sp_tvb,
13319                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
13320                                     top_tree);
13321
13322                                 /* In case we did not see the TreeConnect call,
13323                                    store this TID here as well as a IPC TID
13324                                    so we know that future Read/Writes to this
13325                                    TID is (probably) DCERPC.
13326                                 */
13327                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
13328                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
13329                                 }
13330                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
13331                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
13332                                 if (tri != NULL)
13333                                         tri->subcmd=TRANSACTION_MAILSLOT;
13334
13335                                 /*
13336                                  * A tvbuff containing the setup words and
13337                                  * the mailslot path.
13338                                  */
13339                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13340                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
13341                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
13342                         }
13343                         if (!dissected_trans)
13344                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13345                 } else {
13346                         if(check_col(pinfo->cinfo, COL_INFO)){
13347                                 col_append_str(pinfo->cinfo, COL_INFO,
13348                                         "[transact continuation]");
13349                         }
13350                 }
13351         }
13352
13353         END_OF_SMB
13354
13355         return offset;
13356 }
13357
13358
13359
13360 static int
13361 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13362     int offset, guint16 *bcp, gboolean *trunc)
13363 {
13364         int fn_len;
13365         const char *fn;
13366         int old_offset = offset;
13367         proto_item *item = NULL;
13368         proto_tree *tree = NULL;
13369         smb_info_t *si;
13370         smb_transact2_info_t *t2i;
13371         gboolean resume_keys = FALSE;
13372
13373         si = (smb_info_t *)pinfo->private_data;
13374         DISSECTOR_ASSERT(si);
13375
13376         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13377                 t2i = si->sip->extra_info;
13378                 if (t2i != NULL)
13379                         resume_keys = t2i->resume_keys;
13380         }
13381
13382         if(parent_tree){
13383                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13384                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13385                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13386                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13387         }
13388
13389         if (resume_keys) {
13390                 /* resume key */
13391                 CHECK_BYTE_COUNT_SUBR(4);
13392                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13393                 COUNT_BYTES_SUBR(4);
13394         }
13395
13396         /* create time */
13397         CHECK_BYTE_COUNT_SUBR(4);
13398         offset = dissect_smb_datetime(tvb, tree, offset,
13399                 hf_smb_create_time,
13400                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13401         *bcp -= 4;
13402
13403         /* access time */
13404         CHECK_BYTE_COUNT_SUBR(4);
13405         offset = dissect_smb_datetime(tvb, tree, offset,
13406                 hf_smb_access_time,
13407                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13408         *bcp -= 4;
13409
13410         /* last write time */
13411         CHECK_BYTE_COUNT_SUBR(4);
13412         offset = dissect_smb_datetime(tvb, tree, offset,
13413                 hf_smb_last_write_time,
13414                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13415         *bcp -= 4;
13416
13417         /* data size */
13418         CHECK_BYTE_COUNT_SUBR(4);
13419         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13420         COUNT_BYTES_SUBR(4);
13421
13422         /* allocation size */
13423         CHECK_BYTE_COUNT_SUBR(4);
13424         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13425         COUNT_BYTES_SUBR(4);
13426
13427         /* File Attributes */
13428         CHECK_BYTE_COUNT_SUBR(2);
13429         offset = dissect_file_attributes(tvb, tree, offset, 2);
13430         *bcp -= 2;
13431
13432         /* file name len */
13433         CHECK_BYTE_COUNT_SUBR(1);
13434         fn_len = tvb_get_guint8(tvb, offset);
13435         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13436         COUNT_BYTES_SUBR(1);
13437         if (si->unicode)
13438                 fn_len += 2;    /* include terminating '\0' */
13439         else
13440                 fn_len++;       /* include terminating '\0' */
13441
13442         /* file name */
13443         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13444         CHECK_STRING_SUBR(fn);
13445         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13446                 fn);
13447         COUNT_BYTES_SUBR(fn_len);
13448
13449         if (check_col(pinfo->cinfo, COL_INFO)) {
13450                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13451                     format_text(fn, strlen(fn)));
13452         }
13453
13454         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13455         proto_item_set_len(item, offset-old_offset);
13456
13457         *trunc = FALSE;
13458         return offset;
13459 }
13460
13461 static int
13462 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13463     int offset, guint16 *bcp, gboolean *trunc)
13464 {
13465         int fn_len;
13466         const char *fn;
13467         int old_offset = offset;
13468         proto_item *item = NULL;
13469         proto_tree *tree = NULL;
13470         smb_info_t *si;
13471         smb_transact2_info_t *t2i;
13472         gboolean resume_keys = FALSE;
13473
13474         si = (smb_info_t *)pinfo->private_data;
13475         DISSECTOR_ASSERT(si);
13476
13477         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13478                 t2i = si->sip->extra_info;
13479                 if (t2i != NULL)
13480                         resume_keys = t2i->resume_keys;
13481         }
13482
13483         if(parent_tree){
13484                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13485                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13486                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13487                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13488         }
13489
13490         if (resume_keys) {
13491                 /* resume key */
13492                 CHECK_BYTE_COUNT_SUBR(4);
13493                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13494                 COUNT_BYTES_SUBR(4);
13495         }
13496
13497         /* create time */
13498         CHECK_BYTE_COUNT_SUBR(4);
13499         offset = dissect_smb_datetime(tvb, tree, offset,
13500                 hf_smb_create_time,
13501                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13502         *bcp -= 4;
13503
13504         /* access time */
13505         CHECK_BYTE_COUNT_SUBR(4);
13506         offset = dissect_smb_datetime(tvb, tree, offset,
13507                 hf_smb_access_time,
13508                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13509         *bcp -= 4;
13510
13511         /* last write time */
13512         CHECK_BYTE_COUNT_SUBR(4);
13513         offset = dissect_smb_datetime(tvb, tree, offset,
13514                 hf_smb_last_write_time,
13515                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13516         *bcp -= 4;
13517
13518         /* data size */
13519         CHECK_BYTE_COUNT_SUBR(4);
13520         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13521         COUNT_BYTES_SUBR(4);
13522
13523         /* allocation size */
13524         CHECK_BYTE_COUNT_SUBR(4);
13525         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13526         COUNT_BYTES_SUBR(4);
13527
13528         /* File Attributes */
13529         CHECK_BYTE_COUNT_SUBR(2);
13530         offset = dissect_file_attributes(tvb, tree, offset, 2);
13531         *bcp -= 2;
13532
13533         /* ea length */
13534         CHECK_BYTE_COUNT_SUBR(4);
13535         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13536         COUNT_BYTES_SUBR(4);
13537
13538         /* file name len */
13539         CHECK_BYTE_COUNT_SUBR(1);
13540         fn_len = tvb_get_guint8(tvb, offset);
13541         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13542         COUNT_BYTES_SUBR(1);
13543         if (si->unicode)
13544                 fn_len += 2;    /* include terminating '\0' */
13545         else
13546                 fn_len++;       /* include terminating '\0' */
13547
13548         /* file name */
13549         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13550         CHECK_STRING_SUBR(fn);
13551         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13552                 fn);
13553         COUNT_BYTES_SUBR(fn_len);
13554
13555         if (check_col(pinfo->cinfo, COL_INFO)) {
13556                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13557                     format_text(fn, strlen(fn)));
13558         }
13559
13560         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13561         proto_item_set_len(item, offset-old_offset);
13562
13563         *trunc = FALSE;
13564         return offset;
13565 }
13566
13567 static int
13568 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13569     int offset, guint16 *bcp, gboolean *trunc)
13570 {
13571         int fn_len;
13572         const char *fn;
13573         int old_offset = offset;
13574         proto_item *item = NULL;
13575         proto_tree *tree = NULL;
13576         smb_info_t *si;
13577         guint32 neo;
13578         int padcnt;
13579
13580         si = (smb_info_t *)pinfo->private_data;
13581         DISSECTOR_ASSERT(si);
13582
13583         if(parent_tree){
13584                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13585                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13586                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13587                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13588         }
13589
13590         /*
13591          * We assume that the presence of a next entry offset implies the
13592          * absence of a resume key, as appears to be the case for 4.3.4.6.
13593          */
13594
13595         /* next entry offset */
13596         CHECK_BYTE_COUNT_SUBR(4);
13597         neo = tvb_get_letohl(tvb, offset);
13598         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13599         COUNT_BYTES_SUBR(4);
13600
13601         /* file index */
13602         CHECK_BYTE_COUNT_SUBR(4);
13603         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13604         COUNT_BYTES_SUBR(4);
13605
13606         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13607         if (*trunc) {
13608           return offset;
13609         }
13610
13611         /* end of file */
13612         CHECK_BYTE_COUNT_SUBR(8);
13613         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13614         COUNT_BYTES_SUBR(8);
13615
13616         /* allocation size */
13617         CHECK_BYTE_COUNT_SUBR(8);
13618         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13619         COUNT_BYTES_SUBR(8);
13620
13621         /* Extended File Attributes */
13622         CHECK_BYTE_COUNT_SUBR(4);
13623         offset = dissect_file_ext_attr(tvb, tree, offset);
13624         *bcp -= 4;
13625
13626         /* file name len */
13627         CHECK_BYTE_COUNT_SUBR(4);
13628         fn_len = tvb_get_letohl(tvb, offset);
13629         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13630         COUNT_BYTES_SUBR(4);
13631
13632         /* file name */
13633         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13634         CHECK_STRING_SUBR(fn);
13635         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13636                 fn);
13637         COUNT_BYTES_SUBR(fn_len);
13638
13639         if (check_col(pinfo->cinfo, COL_INFO)) {
13640                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13641                     format_text(fn, strlen(fn)));
13642         }
13643
13644         /* skip to next structure */
13645         if(neo){
13646                 padcnt = (old_offset + neo) - offset;
13647                 if (padcnt < 0) {
13648                         /*
13649                          * XXX - this is bogus; flag it?
13650                          */
13651                         padcnt = 0;
13652                 }
13653                 if (padcnt != 0) {
13654                         CHECK_BYTE_COUNT_SUBR(padcnt);
13655                         COUNT_BYTES_SUBR(padcnt);
13656                 }
13657         }
13658
13659         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13660         proto_item_set_len(item, offset-old_offset);
13661
13662         *trunc = FALSE;
13663         return offset;
13664 }
13665
13666 static int
13667 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13668     int offset, guint16 *bcp, gboolean *trunc)
13669 {
13670         int fn_len;
13671         const char *fn;
13672         int old_offset = offset;
13673         proto_item *item = NULL;
13674         proto_tree *tree = NULL;
13675         smb_info_t *si;
13676         guint32 neo;
13677         int padcnt;
13678
13679         si = (smb_info_t *)pinfo->private_data;
13680         DISSECTOR_ASSERT(si);
13681
13682         if(parent_tree){
13683                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13684                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13685                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13686                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13687         }
13688
13689         /*
13690          * We assume that the presence of a next entry offset implies the
13691          * absence of a resume key, as appears to be the case for 4.3.4.6.
13692          */
13693
13694         /* next entry offset */
13695         CHECK_BYTE_COUNT_SUBR(4);
13696         neo = tvb_get_letohl(tvb, offset);
13697         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13698         COUNT_BYTES_SUBR(4);
13699
13700         /* file index */
13701         CHECK_BYTE_COUNT_SUBR(4);
13702         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13703         COUNT_BYTES_SUBR(4);
13704
13705         /* standard 8-byte timestamps */
13706         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13707         if (*trunc) {
13708           return offset;
13709         }
13710
13711         /* end of file */
13712         CHECK_BYTE_COUNT_SUBR(8);
13713         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13714         COUNT_BYTES_SUBR(8);
13715
13716         /* allocation size */
13717         CHECK_BYTE_COUNT_SUBR(8);
13718         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13719         COUNT_BYTES_SUBR(8);
13720
13721         /* Extended File Attributes */
13722         CHECK_BYTE_COUNT_SUBR(4);
13723         offset = dissect_file_ext_attr(tvb, tree, offset);
13724         *bcp -= 4;
13725
13726         /* file name len */
13727         CHECK_BYTE_COUNT_SUBR(4);
13728         fn_len = tvb_get_letohl(tvb, offset);
13729         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13730         COUNT_BYTES_SUBR(4);
13731
13732         /* ea length */
13733         CHECK_BYTE_COUNT_SUBR(4);
13734         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13735         COUNT_BYTES_SUBR(4);
13736
13737         /* file name */
13738         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13739         CHECK_STRING_SUBR(fn);
13740         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13741                 fn);
13742         COUNT_BYTES_SUBR(fn_len);
13743
13744         if (check_col(pinfo->cinfo, COL_INFO)) {
13745                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13746                     format_text(fn, strlen(fn)));
13747         }
13748
13749         /* skip to next structure */
13750         if(neo){
13751                 padcnt = (old_offset + neo) - offset;
13752                 if (padcnt < 0) {
13753                         /*
13754                          * XXX - this is bogus; flag it?
13755                          */
13756                         padcnt = 0;
13757                 }
13758                 if (padcnt != 0) {
13759                         CHECK_BYTE_COUNT_SUBR(padcnt);
13760                         COUNT_BYTES_SUBR(padcnt);
13761                 }
13762         }
13763
13764         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13765         proto_item_set_len(item, offset-old_offset);
13766
13767         *trunc = FALSE;
13768         return offset;
13769 }
13770
13771 static int
13772 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13773     int offset, guint16 *bcp, gboolean *trunc)
13774 {
13775         int fn_len, sfn_len;
13776         const char *fn, *sfn;
13777         int old_offset = offset;
13778         proto_item *item = NULL;
13779         proto_tree *tree = NULL;
13780         smb_info_t *si;
13781         guint32 neo;
13782         int padcnt;
13783
13784         si = (smb_info_t *)pinfo->private_data;
13785         DISSECTOR_ASSERT(si);
13786
13787         if(parent_tree){
13788                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13789                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13790                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13791                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13792         }
13793
13794         /*
13795          * XXX - I have not seen any of these that contain a resume
13796          * key, even though some of the requests had the "return resume
13797          * key" flag set.
13798          */
13799
13800         /* next entry offset */
13801         CHECK_BYTE_COUNT_SUBR(4);
13802         neo = tvb_get_letohl(tvb, offset);
13803         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13804         COUNT_BYTES_SUBR(4);
13805
13806         /* file index */
13807         CHECK_BYTE_COUNT_SUBR(4);
13808         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13809         COUNT_BYTES_SUBR(4);
13810
13811         /* dissect standard 8-byte timestamps */
13812         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13813         if (*trunc) {
13814           return offset;
13815         }
13816
13817         /* end of file */
13818         CHECK_BYTE_COUNT_SUBR(8);
13819         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13820         COUNT_BYTES_SUBR(8);
13821
13822         /* allocation size */
13823         CHECK_BYTE_COUNT_SUBR(8);
13824         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13825         COUNT_BYTES_SUBR(8);
13826
13827         /* Extended File Attributes */
13828         CHECK_BYTE_COUNT_SUBR(4);
13829         offset = dissect_file_ext_attr(tvb, tree, offset);
13830         *bcp -= 4;
13831
13832         /* file name len */
13833         CHECK_BYTE_COUNT_SUBR(4);
13834         fn_len = tvb_get_letohl(tvb, offset);
13835         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13836         COUNT_BYTES_SUBR(4);
13837
13838         /*
13839          * EA length.
13840          *
13841          * XXX - in one captures, this has the topmost bit set, and the
13842          * rest of the bits have the value 7.  Is the topmost bit being
13843          * set some indication that the value *isn't* the length of
13844          * the EAs?
13845          */
13846         CHECK_BYTE_COUNT_SUBR(4);
13847         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13848         COUNT_BYTES_SUBR(4);
13849
13850         /* short file name len */
13851         CHECK_BYTE_COUNT_SUBR(1);
13852         sfn_len = tvb_get_guint8(tvb, offset);
13853         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
13854         COUNT_BYTES_SUBR(1);
13855
13856         /* reserved byte */
13857         CHECK_BYTE_COUNT_SUBR(1);
13858         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13859         COUNT_BYTES_SUBR(1);
13860
13861         /* short file name - it's not always in Unicode */
13862         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
13863         CHECK_STRING_SUBR(sfn);
13864         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
13865                 sfn);
13866         COUNT_BYTES_SUBR(24);
13867
13868         /* file name */
13869         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13870         CHECK_STRING_SUBR(fn);
13871         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13872                 fn);
13873         COUNT_BYTES_SUBR(fn_len);
13874
13875         if (check_col(pinfo->cinfo, COL_INFO)) {
13876                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13877                     format_text(fn, strlen(fn)));
13878         }
13879
13880         /* skip to next structure */
13881         if(neo){
13882                 padcnt = (old_offset + neo) - offset;
13883                 if (padcnt < 0) {
13884                         /*
13885                          * XXX - this is bogus; flag it?
13886                          */
13887                         padcnt = 0;
13888                 }
13889                 if (padcnt != 0) {
13890                         CHECK_BYTE_COUNT_SUBR(padcnt);
13891                         COUNT_BYTES_SUBR(padcnt);
13892                 }
13893         }
13894
13895         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13896         proto_item_set_len(item, offset-old_offset);
13897
13898         *trunc = FALSE;
13899         return offset;
13900 }
13901
13902 static int
13903 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13904     int offset, guint16 *bcp, gboolean *trunc)
13905 {
13906         int fn_len;
13907         const char *fn;
13908         int old_offset = offset;
13909         proto_item *item = NULL;
13910         proto_tree *tree = NULL;
13911         smb_info_t *si;
13912         guint32 neo;
13913         int padcnt;
13914
13915         si = (smb_info_t *)pinfo->private_data;
13916         DISSECTOR_ASSERT(si);
13917
13918         if(parent_tree){
13919                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13920                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13921                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13922                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13923         }
13924
13925         /*
13926          * We assume that the presence of a next entry offset implies the
13927          * absence of a resume key, as appears to be the case for 4.3.4.6.
13928          */
13929
13930         /* next entry offset */
13931         CHECK_BYTE_COUNT_SUBR(4);
13932         neo = tvb_get_letohl(tvb, offset);
13933         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13934         COUNT_BYTES_SUBR(4);
13935
13936         /* file index */
13937         CHECK_BYTE_COUNT_SUBR(4);
13938         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13939         COUNT_BYTES_SUBR(4);
13940
13941         /* file name len */
13942         CHECK_BYTE_COUNT_SUBR(4);
13943         fn_len = tvb_get_letohl(tvb, offset);
13944         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13945         COUNT_BYTES_SUBR(4);
13946
13947         /* file name */
13948         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13949         CHECK_STRING_SUBR(fn);
13950         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13951                 fn);
13952         COUNT_BYTES_SUBR(fn_len);
13953
13954         if (check_col(pinfo->cinfo, COL_INFO)) {
13955                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13956                     format_text(fn, strlen(fn)));
13957         }
13958
13959         /* skip to next structure */
13960         if(neo){
13961                 padcnt = (old_offset + neo) - offset;
13962                 if (padcnt < 0) {
13963                         /*
13964                          * XXX - this is bogus; flag it?
13965                          */
13966                         padcnt = 0;
13967                 }
13968                 if (padcnt != 0) {
13969                         CHECK_BYTE_COUNT_SUBR(padcnt);
13970                         COUNT_BYTES_SUBR(padcnt);
13971                 }
13972         }
13973
13974         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13975         proto_item_set_len(item, offset-old_offset);
13976
13977         *trunc = FALSE;
13978         return offset;
13979 }
13980
13981 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13982
13983 static int
13984 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13985                 proto_tree *tree, int offset, guint16 *bcp,
13986                 gboolean *trunc)
13987 {
13988         smb_info_t *si = pinfo->private_data;
13989         const char *fn;
13990         int fn_len;
13991
13992         DISSECTOR_ASSERT(si);
13993
13994         /* NextEntryOffset */
13995         CHECK_BYTE_COUNT_SUBR(4);
13996         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13997         COUNT_BYTES_SUBR(4);
13998
13999         /* ResumeKey */
14000         CHECK_BYTE_COUNT_SUBR(4);
14001         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
14002         COUNT_BYTES_SUBR(4);
14003
14004         /* End of file (file size) */
14005         CHECK_BYTE_COUNT_SUBR(8);
14006         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
14007         COUNT_BYTES_SUBR(8);
14008
14009         /* Number of bytes */
14010         CHECK_BYTE_COUNT_SUBR(8);
14011         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
14012         COUNT_BYTES_SUBR(8);
14013
14014         /* Last status change */
14015         CHECK_BYTE_COUNT_SUBR(8);
14016         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
14017         *bcp -= 8;
14018
14019         /* Last access time */
14020         CHECK_BYTE_COUNT_SUBR(8);
14021         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
14022         *bcp -= 8;
14023
14024         /* Last modification time */
14025         CHECK_BYTE_COUNT_SUBR(8);
14026         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
14027         *bcp -= 8;
14028
14029         /* File owner uid */
14030         CHECK_BYTE_COUNT_SUBR(8);
14031         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
14032         COUNT_BYTES_SUBR(8);
14033
14034         /* File group gid */
14035         CHECK_BYTE_COUNT_SUBR(8);
14036         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
14037         COUNT_BYTES_SUBR(8);
14038
14039         /* File type */
14040         CHECK_BYTE_COUNT_SUBR(4);
14041         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
14042         COUNT_BYTES_SUBR(4);
14043
14044         /* Major device number */
14045         CHECK_BYTE_COUNT_SUBR(8);
14046         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
14047         COUNT_BYTES_SUBR(8);
14048
14049         /* Minor device number */
14050         CHECK_BYTE_COUNT_SUBR(8);
14051         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
14052         COUNT_BYTES_SUBR(8);
14053
14054         /* Unique id */
14055         CHECK_BYTE_COUNT_SUBR(8);
14056         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
14057         COUNT_BYTES_SUBR(8);
14058
14059         /* Permissions */
14060         CHECK_BYTE_COUNT_SUBR(8);
14061         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
14062         COUNT_BYTES_SUBR(8);
14063
14064         /* Nlinks */
14065         CHECK_BYTE_COUNT_SUBR(8);
14066         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
14067         COUNT_BYTES_SUBR(8);
14068
14069         /* Name */
14070
14071         fn = get_unicode_or_ascii_string(
14072                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
14073
14074         CHECK_STRING_SUBR(fn);
14075         proto_tree_add_string(
14076                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
14077         COUNT_BYTES_SUBR(fn_len);
14078
14079         /* Pad to 4 bytes */
14080
14081         if (offset % 4)
14082                 offset += 4 - (offset % 4);
14083
14084         *trunc = FALSE;
14085         return offset;
14086 }
14087
14088 /*dissect the data block for TRANS2_FIND_FIRST2*/
14089 static int
14090 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
14091     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
14092 {
14093         smb_info_t *si;
14094
14095         if(!*bcp){
14096                 return offset;
14097         }
14098
14099         si = (smb_info_t *)pinfo->private_data;
14100         DISSECTOR_ASSERT(si);
14101
14102         switch(si->info_level){
14103         case 1:         /*Info Standard*/
14104                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
14105                     trunc);
14106                 break;
14107         case 2:         /*Info Query EA Size*/
14108                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
14109                     trunc);
14110                 break;
14111         case 3:         /*Info Query EAs From List same as
14112                                 InfoQueryEASize*/
14113                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
14114                     trunc);
14115                 break;
14116         case 0x0101:    /*Find File Directory Info*/
14117                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
14118                     trunc);
14119                 break;
14120         case 0x0102:    /*Find File Full Directory Info*/
14121                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
14122                     trunc);
14123                 break;
14124         case 0x0103:    /*Find File Names Info*/
14125                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
14126                     trunc);
14127                 break;
14128         case 0x0104:    /*Find File Both Directory Info*/
14129                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
14130                     trunc);
14131                 break;
14132         case 0x0202:    /*Find File UNIX*/
14133                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
14134                     trunc);
14135                 break;
14136         default:        /* unknown info level */
14137                 *trunc = FALSE;
14138                 break;
14139         }
14140         return offset;
14141 }
14142
14143
14144 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
14145 static int
14146 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14147 {
14148         guint32 mask;
14149         proto_item *item;
14150         proto_tree *tree;
14151
14152         mask = tvb_get_letohl(tvb, offset);
14153
14154         if(parent_tree){
14155                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
14156                         "FS Attributes: 0x%08x", mask);
14157                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
14158
14159                 /* case sensitive search */
14160                 proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
14161                         tvb, offset, 4, mask);
14162                 /* case preserved names */
14163                 proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
14164                         tvb, offset, 4, mask);
14165                 /* unicode on disk */
14166                 proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
14167                         tvb, offset, 4, mask);
14168                 /* persistent acls */
14169                 proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
14170                         tvb, offset, 4, mask);
14171                 /* file compression */
14172                 proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
14173                         tvb, offset, 4, mask);
14174                 /* volume quotas */
14175                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
14176                         tvb, offset, 4, mask);
14177                 /* sparse files */
14178                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
14179                         tvb, offset, 4, mask);
14180                 /* reparse points */
14181                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
14182                         tvb, offset, 4, mask);
14183                 /* remote storage */
14184                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
14185                         tvb, offset, 4, mask);
14186                 /* lfn apis */
14187                 proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
14188                         tvb, offset, 4, mask);
14189                 /* volume is compressed */
14190                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
14191                         tvb, offset, 4, mask);
14192                 /* support oids */
14193                 proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
14194                         tvb, offset, 4, mask);
14195                 /* encryption */
14196                 proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
14197                         tvb, offset, 4, mask);
14198                 /* named streams */
14199                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
14200                         tvb, offset, 4, mask);
14201                 /* read only volume */
14202                 proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
14203                         tvb, offset, 4, mask);
14204         }
14205
14206         offset += 4;
14207         return offset;
14208 }
14209
14210
14211 static int
14212 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14213 {
14214         guint32 mask;
14215         proto_item *item;
14216         proto_tree *tree;
14217
14218         mask = tvb_get_letohl(tvb, offset);
14219
14220         if(parent_tree){
14221                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
14222                         "Device Characteristics: 0x%08x", mask);
14223                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
14224
14225                 proto_tree_add_boolean(tree, hf_smb_device_char_removable,
14226                         tvb, offset, 4, mask);
14227                 proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
14228                         tvb, offset, 4, mask);
14229                 proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
14230                         tvb, offset, 4, mask);
14231                 proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
14232                         tvb, offset, 4, mask);
14233                 proto_tree_add_boolean(tree, hf_smb_device_char_remote,
14234                         tvb, offset, 4, mask);
14235                 proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
14236                         tvb, offset, 4, mask);
14237                 proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
14238                         tvb, offset, 4, mask);
14239         }
14240
14241         offset += 4;
14242         return offset;
14243 }
14244
14245 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
14246
14247 static const true_false_string tfs_smb_mac_access_ctrl = {
14248   "Macintosh Access Control Supported",
14249   "Macintosh Access Control Not Supported"
14250 };
14251
14252 static const true_false_string tfs_smb_mac_getset_comments = {
14253   "Macintosh Get & Set Comments Supported",
14254   "Macintosh Get & Set Comments Not Supported"
14255 };
14256
14257 static const true_false_string tfs_smb_mac_desktopdb_calls = {
14258   "Macintosh Get & Set Desktop Database Info Supported",
14259   "Macintosh Get & Set Desktop Database Info Supported"
14260 };
14261
14262 static const true_false_string tfs_smb_mac_unique_ids = {
14263   "Macintosh Unique IDs Supported",
14264   "Macintosh Unique IDs Not Supported"
14265 };
14266
14267 static const true_false_string tfs_smb_mac_streams = {
14268   "Macintosh and Streams Extensions Not Supported",
14269   "Macintosh and Streams Extensions Supported"
14270 };
14271
14272 int
14273 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14274 {
14275         int fn_len, vll;
14276         const char *fn;
14277
14278         /* create time */
14279         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14280         offset = dissect_nt_64bit_time(tvb, tree, offset,
14281                 hf_smb_create_time);
14282         *bcp -= 8;
14283
14284         /* volume serial number */
14285         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14286         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14287         COUNT_BYTES_TRANS_SUBR(4);
14288
14289         /* volume label length */
14290         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14291         vll = tvb_get_letohl(tvb, offset);
14292         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14293         COUNT_BYTES_TRANS_SUBR(4);
14294
14295         /* 2 reserved bytes */
14296         CHECK_BYTE_COUNT_TRANS_SUBR(2);
14297         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14298         COUNT_BYTES_TRANS_SUBR(2);
14299
14300         /* label */
14301         fn_len = vll;
14302         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14303         CHECK_STRING_TRANS_SUBR(fn);
14304         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14305                 fn);
14306         COUNT_BYTES_TRANS_SUBR(fn_len);
14307
14308         return offset;
14309 }
14310
14311 int
14312 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14313 {
14314         /* allocation size */
14315         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14316         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14317         COUNT_BYTES_TRANS_SUBR(8);
14318
14319         /* free allocation units */
14320         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14321         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
14322         COUNT_BYTES_TRANS_SUBR(8);
14323
14324         /* sectors per unit */
14325         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14326         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14327         COUNT_BYTES_TRANS_SUBR(4);
14328
14329         /* bytes per sector */
14330         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14331         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14332         COUNT_BYTES_TRANS_SUBR(4);
14333
14334         return offset;
14335 }
14336
14337 int
14338 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14339 {
14340         /* device type */
14341         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14342         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
14343         COUNT_BYTES_TRANS_SUBR(4);
14344
14345         /* device characteristics */
14346         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14347         offset = dissect_device_characteristics(tvb, tree, offset);
14348         *bcp -= 4;
14349
14350         return offset;
14351 }
14352
14353 int
14354 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14355 {
14356         int fn_len, fnl;
14357         const char *fn;
14358
14359         /* FS attributes */
14360         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14361         offset = dissect_fs_attributes(tvb, tree, offset);
14362         *bcp -= 4;
14363
14364         /* max name len */
14365         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14366         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
14367         COUNT_BYTES_TRANS_SUBR(4);
14368
14369         /* fs name length */
14370         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14371         fnl = tvb_get_letohl(tvb, offset);
14372         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
14373         COUNT_BYTES_TRANS_SUBR(4);
14374
14375         /* label */
14376         fn_len = fnl;
14377         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14378         CHECK_STRING_TRANS_SUBR(fn);
14379         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
14380                 fn);
14381         COUNT_BYTES_TRANS_SUBR(fn_len);
14382
14383         return offset;
14384 }
14385
14386 int
14387 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
14388 {
14389         CHECK_BYTE_COUNT_TRANS_SUBR(64);
14390
14391         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
14392
14393         COUNT_BYTES_TRANS_SUBR(64);
14394
14395         return offset;
14396 }
14397
14398 int
14399 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14400 {
14401         /* allocation size */
14402         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14403         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14404         COUNT_BYTES_TRANS_SUBR(8);
14405
14406         /* caller free allocation units */
14407         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14408         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
14409         COUNT_BYTES_TRANS_SUBR(8);
14410
14411         /* actual free allocation units */
14412         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14413         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
14414         COUNT_BYTES_TRANS_SUBR(8);
14415
14416         /* sectors per unit */
14417         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14418         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14419         COUNT_BYTES_TRANS_SUBR(4);
14420
14421         /* bytes per sector */
14422         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14423         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14424         COUNT_BYTES_TRANS_SUBR(4);
14425
14426         return offset;
14427 }
14428
14429 static int
14430 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
14431     int offset, guint16 *bcp)
14432 {
14433         smb_info_t *si;
14434         int fn_len, vll;
14435         const char *fn;
14436         guint support = 0;
14437         proto_item *item = NULL;
14438         proto_tree *ti = NULL;
14439
14440         if(!*bcp){
14441                 return offset;
14442         }
14443
14444         si = (smb_info_t *)pinfo->private_data;
14445         DISSECTOR_ASSERT(si);
14446
14447         switch(si->info_level){
14448         case 1:         /* SMB_INFO_ALLOCATION */
14449                 /* filesystem id */
14450                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14451                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
14452                 COUNT_BYTES_TRANS_SUBR(4);
14453
14454                 /* sectors per unit */
14455                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14456                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14457                 COUNT_BYTES_TRANS_SUBR(4);
14458
14459                 /* units */
14460                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14461                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
14462                 COUNT_BYTES_TRANS_SUBR(4);
14463
14464                 /* avail units */
14465                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14466                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
14467                 COUNT_BYTES_TRANS_SUBR(4);
14468
14469                 /* bytes per sector, only 16bit integer here */
14470                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14471                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14472                 COUNT_BYTES_TRANS_SUBR(2);
14473
14474                 break;
14475         case 2:         /* SMB_INFO_VOLUME */
14476                 /* volume serial number */
14477                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14478                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14479                 COUNT_BYTES_TRANS_SUBR(4);
14480
14481                 /* volume label length, only one byte here */
14482                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
14483                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
14484                 COUNT_BYTES_TRANS_SUBR(1);
14485
14486                 /* label */
14487                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
14488                 CHECK_STRING_TRANS_SUBR(fn);
14489                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14490                         fn);
14491                 COUNT_BYTES_TRANS_SUBR(fn_len);
14492
14493                 break;
14494         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
14495         case 1002:      /* SMB_FS_LABEL_INFORMATION */
14496                 /* volume label length */
14497                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14498                 vll = tvb_get_letohl(tvb, offset);
14499                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14500                 COUNT_BYTES_TRANS_SUBR(4);
14501
14502                 /* label */
14503                 fn_len = vll;
14504                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14505                 CHECK_STRING_TRANS_SUBR(fn);
14506                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14507                         fn);
14508                 COUNT_BYTES_TRANS_SUBR(fn_len);
14509
14510                 break;
14511         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
14512         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
14513                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14514                 break;
14515         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
14516         case 1003:      /* SMB_FS_SIZE_INFORMATION */
14517                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14518                 break;
14519         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
14520         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
14521                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
14522                 break;
14523         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
14524         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
14525                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14526                 break;
14527         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
14528                 proto_item *item = NULL;
14529                 proto_tree *subtree = NULL;
14530                 guint32 caps_lo, caps_hi;
14531
14532                 /* MajorVersionNumber */
14533                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14534                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
14535                 COUNT_BYTES_TRANS_SUBR(2);
14536
14537                 /* MinorVersionNumber */
14538                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14539                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
14540                 COUNT_BYTES_TRANS_SUBR(2);
14541
14542                 /* Capability */
14543
14544                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14545
14546                 caps_lo = tvb_get_letohl(tvb, offset);
14547                 caps_hi = tvb_get_letohl(tvb, offset + 4);
14548
14549                 if (tree) {
14550                         item = proto_tree_add_text(
14551                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x",
14552                                 caps_hi, caps_lo);
14553                         subtree = proto_item_add_subtree(
14554                                 item, ett_smb_unix_capabilities);
14555                 }
14556
14557                 proto_tree_add_boolean(
14558                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8,
14559                         caps_lo);
14560
14561                 proto_tree_add_boolean(
14562                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8,
14563                         caps_lo);
14564
14565                 COUNT_BYTES_TRANS_SUBR(8);
14566
14567                 break;
14568         }
14569         case 0x301:     /* MAC_QUERY_FS_INFO */
14570                 /* Create time */
14571                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14572                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
14573                 *bcp -= 8;
14574                 /* Modify Time */
14575                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14576                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
14577                 *bcp -= 8;
14578                 /* Backup Time */
14579                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14580                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
14581                 *bcp -= 8;
14582                 /* Allocation blocks */
14583                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14584                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
14585                                     offset,
14586                                     4, TRUE);
14587                 COUNT_BYTES_TRANS_SUBR(4);
14588                 /* Allocation Block Size */
14589                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14590                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
14591                                     offset, 4, TRUE);
14592                 COUNT_BYTES_TRANS_SUBR(4);
14593                 /* Free Block Count */
14594                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14595                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
14596                                     offset, 4, TRUE);
14597                 COUNT_BYTES_TRANS_SUBR(4);
14598                 /* Finder Info ... */
14599                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
14600                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
14601                                             offset, 32,
14602                                             tvb_get_ptr(tvb, offset,32),
14603                                             "Finder Info: %s",
14604                                             tvb_format_text(tvb, offset, 32));
14605                 COUNT_BYTES_TRANS_SUBR(32);
14606                 /* Number Files */
14607                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14608                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
14609                                     offset, 4, TRUE);
14610                 COUNT_BYTES_TRANS_SUBR(4);
14611                 /* Number of Root Directories */
14612                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14613                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
14614                                     offset, 4, TRUE);
14615                 COUNT_BYTES_TRANS_SUBR(4);
14616                 /* Number of files */
14617                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14618                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
14619                                     offset, 4, TRUE);
14620                 COUNT_BYTES_TRANS_SUBR(4);
14621                 /* Dir Count */
14622                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14623                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
14624                                     offset, 4, TRUE);
14625                 COUNT_BYTES_TRANS_SUBR(4);
14626                 /* Mac Support Flags */
14627                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14628                 support = tvb_get_ntohl(tvb, offset);
14629                 item = proto_tree_add_text(tree, tvb, offset, 4,
14630                                            "Mac Support Flags: 0x%08x", support);
14631                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
14632                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
14633                                        tvb, offset, 4, support);
14634                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
14635                                        tvb, offset, 4, support);
14636                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
14637                                        tvb, offset, 4, support);
14638                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
14639                                        tvb, offset, 4, support);
14640                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
14641                                        tvb, offset, 4, support);
14642                 COUNT_BYTES_TRANS_SUBR(4);
14643                 break;
14644         case 1006:      /* QUERY_FS_QUOTA_INFO */
14645                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
14646                 break;
14647         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
14648                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14649                 break;
14650         case 1008: /* Query Object ID */ {
14651                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
14652                 break;
14653             }
14654         }
14655
14656         return offset;
14657 }
14658
14659 static int
14660 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
14661     proto_tree *parent_tree)
14662 {
14663         proto_item *item = NULL;
14664         proto_tree *tree = NULL;
14665         smb_info_t *si;
14666         smb_transact2_info_t *t2i;
14667         int count;
14668         gboolean trunc;
14669         int offset = 0;
14670         guint16 dc;
14671
14672         dc = tvb_reported_length(tvb);
14673
14674         si = (smb_info_t *)pinfo->private_data;
14675         DISSECTOR_ASSERT(si);
14676
14677         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14678                 t2i = si->sip->extra_info;
14679         else
14680                 t2i = NULL;
14681
14682         if(parent_tree){
14683                 if (t2i != NULL && t2i->subcmd != -1) {
14684                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14685                                 "%s Data",
14686                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14687                                         "Unknown (0x%02x)"));
14688                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
14689                 } else {
14690                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14691                                 "Unknown Transaction2 Data");
14692                 }
14693         }
14694
14695         if (t2i == NULL) {
14696                 offset += dc;
14697                 return offset;
14698         }
14699         switch(t2i->subcmd){
14700         case 0x00:      /*TRANS2_OPEN2*/
14701                 /* XXX not implemented yet. See SNIA doc */
14702                 break;
14703         case 0x01:      /*TRANS2_FIND_FIRST2*/
14704                 /* returned data */
14705                 count = si->info_count;
14706
14707         if(count == -1) {
14708             break;
14709         }
14710                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14711                         col_append_str(pinfo->cinfo, COL_INFO,
14712                         ", Files:");
14713                 }
14714
14715                 while(count--){
14716                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14717                                 offset, &dc, &trunc);
14718                         if (trunc)
14719                                 break;
14720                 }
14721                 break;
14722         case 0x02:      /*TRANS2_FIND_NEXT2*/
14723                 /* returned data */
14724                 count = si->info_count;
14725
14726         if(count == -1) {
14727             break;
14728         }
14729                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14730                         col_append_str(pinfo->cinfo, COL_INFO,
14731                         ", Files:");
14732                 }
14733
14734                 while(count--){
14735                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14736                                 offset, &dc, &trunc);
14737                         if (trunc)
14738                                 break;
14739                 }
14740                 break;
14741         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14742                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
14743                 break;
14744         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14745                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14746                 break;
14747         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14748                 /* no data in this response */
14749                 break;
14750         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14751                 /* identical to QUERY_PATH_INFO */
14752                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14753                 break;
14754         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14755                 /* no data in this response */
14756                 break;
14757         case 0x09:      /*TRANS2_FSCTL*/
14758                 /* XXX dont know how to dissect this one (yet)*/
14759
14760                 /*
14761                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14762                  * Extensions Version 3.0, Document Version 1.11,
14763                  * July 19, 1990" says this this contains a
14764                  * "File system specific return data block".
14765                  * (That means we may not be able to dissect it in any
14766                  * case.)
14767                  */
14768                 break;
14769         case 0x0a:      /*TRANS2_IOCTL2*/
14770                 /* XXX dont know how to dissect this one (yet)*/
14771
14772                 /*
14773                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14774                  * Extensions Version 3.0, Document Version 1.11,
14775                  * July 19, 1990" says this this contains a
14776                  * "Device/function specific return data block".
14777                  * (That means we may not be able to dissect it in any
14778                  * case.)
14779                  */
14780                 break;
14781         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14782                 /* XXX dont know how to dissect this one (yet)*/
14783
14784                 /*
14785                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14786                  * Extensions Version 3.0, Document Version 1.11,
14787                  * July 19, 1990" says this this contains "the level
14788                  * dependent information about the changes which
14789                  * occurred".
14790                  */
14791                 break;
14792         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14793                 /* XXX dont know how to dissect this one (yet)*/
14794
14795                 /*
14796                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14797                  * Extensions Version 3.0, Document Version 1.11,
14798                  * July 19, 1990" says this this contains "the level
14799                  * dependent information about the changes which
14800                  * occurred".
14801                  */
14802                 break;
14803         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14804                 /* no data in this response */
14805                 break;
14806         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14807                 /* XXX dont know how to dissect this one (yet)*/
14808                 break;
14809         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14810                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
14811                 break;
14812         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14813                 /* the SNIA spec appears to say the response has no data */
14814                 break;
14815         case -1:
14816                 /*
14817                  * We don't know what the matching request was; don't
14818                  * bother putting anything else into the tree for the data.
14819                  */
14820                 offset += dc;
14821                 dc = 0;
14822                 break;
14823         }
14824
14825         /* ooops there were data we didnt know how to process */
14826         if(dc != 0){
14827                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
14828                 offset += dc;
14829         }
14830
14831         return offset;
14832 }
14833
14834
14835 static void
14836 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14837 {
14838         proto_item *item = NULL;
14839         proto_tree *tree = NULL;
14840         smb_info_t *si;
14841         smb_transact2_info_t *t2i;
14842         guint16 fid;
14843         int lno;
14844         int offset = 0;
14845         int pc;
14846
14847         pc = tvb_reported_length(tvb);
14848
14849         si = (smb_info_t *)pinfo->private_data;
14850         DISSECTOR_ASSERT(si);
14851
14852         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14853                 t2i = si->sip->extra_info;
14854         else
14855                 t2i = NULL;
14856
14857         if(parent_tree){
14858                 if (t2i != NULL && t2i->subcmd != -1) {
14859                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14860                                 "%s Parameters",
14861                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14862                                                 "Unknown (0x%02x)"));
14863                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
14864                 } else {
14865                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14866                                 "Unknown Transaction2 Parameters");
14867                 }
14868         }
14869
14870         if (t2i == NULL) {
14871                 offset += pc;
14872                 return;
14873         }
14874         switch(t2i->subcmd){
14875         case 0x00:      /*TRANS2_OPEN2*/
14876                 /* fid */
14877                 fid = tvb_get_letohs(tvb, offset);
14878                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
14879                 offset += 2;
14880
14881                 /*
14882                  * XXX - Microsoft Networks SMB File Sharing Protocol
14883                  * Extensions Version 3.0, Document Version 1.11,
14884                  * July 19, 1990 says that the file attributes, create
14885                  * time (which it says is the last modification time),
14886                  * data size, granted access, file type, and IPC state
14887                  * are returned only if bit 0 is set in the open flags,
14888                  * and that the EA length is returned only if bit 3
14889                  * is set in the open flags.  Does that mean that,
14890                  * at least in that SMB dialect, those fields are not
14891                  * present in the reply parameters if the bits in
14892                  * question aren't set?
14893                  */
14894
14895                 /* File Attributes */
14896                 offset = dissect_file_attributes(tvb, tree, offset, 2);
14897
14898                 /* create time */
14899                 offset = dissect_smb_datetime(tvb, tree, offset,
14900                         hf_smb_create_time,
14901                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
14902
14903                 /* data size */
14904                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
14905                 offset += 4;
14906
14907                 /* granted access */
14908                 offset = dissect_access(tvb, tree, offset, "Granted");
14909
14910                 /* File Type */
14911                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
14912                 offset += 2;
14913
14914                 /* IPC State */
14915                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
14916
14917                 /* open_action */
14918                 offset = dissect_open_action(tvb, tree, offset);
14919
14920                 /* server unique file ID */
14921                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
14922                 offset += 4;
14923
14924                 /* ea error offset, only a 16 bit integer here */
14925                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14926                 offset += 2;
14927
14928                 /* ea length */
14929                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
14930                 offset += 4;
14931
14932                 break;
14933         case 0x01:      /*TRANS2_FIND_FIRST2*/
14934                 /* Find First2 information level */
14935                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
14936
14937                 /* sid */
14938                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
14939                 offset += 2;
14940
14941                 /* search count */
14942                 si->info_count = tvb_get_letohs(tvb, offset);
14943                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14944                 offset += 2;
14945
14946                 /* end of search */
14947                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14948                 offset += 2;
14949
14950                 /* ea error offset, only a 16 bit integer here */
14951                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14952                 offset += 2;
14953
14954                 /* last name offset */
14955                 lno = tvb_get_letohs(tvb, offset);
14956                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14957                 offset += 2;
14958
14959                 break;
14960         case 0x02:      /*TRANS2_FIND_NEXT2*/
14961                 /* search count */
14962                 si->info_count = tvb_get_letohs(tvb, offset);
14963                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14964                 offset += 2;
14965
14966                 /* end of search */
14967                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14968                 offset += 2;
14969
14970                 /* ea_error_offset, only a 16 bit integer here*/
14971                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14972                 offset += 2;
14973
14974                 /* last name offset */
14975                 lno = tvb_get_letohs(tvb, offset);
14976                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14977                 offset += 2;
14978
14979                 break;
14980         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14981                 /* no parameter block here */
14982                 break;
14983         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14984                 /* ea_error_offset, only a 16 bit integer here*/
14985                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14986                 offset += 2;
14987
14988                 break;
14989         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14990                 /* ea_error_offset, only a 16 bit integer here*/
14991                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14992                 offset += 2;
14993
14994                 break;
14995         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14996                 /* ea_error_offset, only a 16 bit integer here*/
14997                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14998                 offset += 2;
14999
15000                 break;
15001         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
15002                 /* ea_error_offset, only a 16 bit integer here*/
15003                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15004                 offset += 2;
15005
15006                 break;
15007         case 0x09:      /*TRANS2_FSCTL*/
15008                 /* XXX dont know how to dissect this one (yet)*/
15009
15010                 /*
15011                  * XXX - "Microsoft Networks SMB File Sharing Protocol
15012                  * Extensions Version 3.0, Document Version 1.11,
15013                  * July 19, 1990" says this this contains a
15014                  * "File system specific return parameter block".
15015                  * (That means we may not be able to dissect it in any
15016                  * case.)
15017                  */
15018                 break;
15019         case 0x0a:      /*TRANS2_IOCTL2*/
15020                 /* XXX dont know how to dissect this one (yet)*/
15021
15022                 /*
15023                  * XXX - "Microsoft Networks SMB File Sharing Protocol
15024                  * Extensions Version 3.0, Document Version 1.11,
15025                  * July 19, 1990" says this this contains a
15026                  * "Device/function specific return parameter block".
15027                  * (That means we may not be able to dissect it in any
15028                  * case.)
15029                  */
15030                 break;
15031         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
15032                 /* Find Notify information level */
15033                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
15034
15035                 /* Monitor handle */
15036                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
15037                 offset += 2;
15038
15039                 /* Change count */
15040                 si->info_count = tvb_get_letohs(tvb, offset);
15041                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
15042                 offset += 2;
15043
15044                 /* ea_error_offset, only a 16 bit integer here*/
15045                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15046                 offset += 2;
15047
15048                 break;
15049         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
15050                 /* Find Notify information level */
15051                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
15052
15053                 /* Change count */
15054                 si->info_count = tvb_get_letohs(tvb, offset);
15055                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
15056                 offset += 2;
15057
15058                 /* ea_error_offset, only a 16 bit integer here*/
15059                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15060                 offset += 2;
15061
15062                 break;
15063         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
15064                 /* ea error offset, only a 16 bit integer here */
15065                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15066                 offset += 2;
15067
15068                 break;
15069         case 0x0e:      /*TRANS2_SESSION_SETUP*/
15070                 /* XXX dont know how to dissect this one (yet)*/
15071                 break;
15072         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
15073                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
15074                 break;
15075         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
15076                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
15077                 break;
15078         case -1:
15079                 /*
15080                  * We don't know what the matching request was; don't
15081                  * bother putting anything else into the tree for the data.
15082                  */
15083                 offset += pc;
15084                 break;
15085         }
15086
15087         /* ooops there were data we didnt know how to process */
15088         if(offset<pc){
15089                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
15090                 offset += pc-offset;
15091         }
15092 }
15093
15094
15095 static int
15096 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15097 {
15098         guint8 sc, wc;
15099         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
15100         smb_info_t *si;
15101         smb_transact2_info_t *t2i = NULL;
15102         guint16 bc;
15103         int padcnt;
15104         gboolean dissected_trans;
15105         fragment_data *r_fd = NULL;
15106         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
15107         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
15108         gboolean save_fragmented;
15109         proto_item *item;
15110
15111         si = (smb_info_t *)pinfo->private_data;
15112         DISSECTOR_ASSERT(si);
15113
15114         switch(si->cmd){
15115         case SMB_COM_TRANSACTION2:
15116                 /* transaction2 */
15117                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
15118                         t2i = si->sip->extra_info;
15119                 } else
15120                         t2i = NULL;
15121                 if (t2i == NULL) {
15122                         /*
15123                          * We didn't see the matching request, so we don't
15124                          * know what type of transaction this is.
15125                          */
15126                         proto_tree_add_text(tree, tvb, 0, 0,
15127                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
15128                         if (check_col(pinfo->cinfo, COL_INFO)) {
15129                                 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
15130                         }
15131                 } else {
15132                         si->info_level = t2i->info_level;
15133                         if (t2i->subcmd == -1) {
15134                                 /*
15135                                  * We didn't manage to extract the subcommand
15136                                  * from the matching request (perhaps because
15137                                  * the frame was short), so we don't know what
15138                                  * type of transaction this is.
15139                                  */
15140                                 proto_tree_add_text(tree, tvb, 0, 0,
15141                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
15142                                 if (check_col(pinfo->cinfo, COL_INFO)) {
15143                                         col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
15144                                 }
15145                         } else {
15146                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
15147                                 /* FIND_FIRST2 */
15148                                 if(t2i && t2i->subcmd==0x0001){
15149                                         item=proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
15150                                         PROTO_ITEM_SET_GENERATED(item);
15151                                         if(t2i->name){
15152                                                 item=proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
15153                                                 PROTO_ITEM_SET_GENERATED(item);
15154                                         }
15155                                 }
15156
15157                                 /* QUERY_PATH_INFORMATION */
15158                                 if(t2i && t2i->subcmd==0x0005){
15159                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
15160                                         PROTO_ITEM_SET_GENERATED(item);
15161                                         if(t2i->name){
15162                                                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
15163                                                 PROTO_ITEM_SET_GENERATED(item);
15164                                         }
15165                                 }
15166                                 /* QUERY_FILE_INFORMATION */
15167                                 if(t2i && t2i->subcmd==0x0007){
15168                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
15169                                         PROTO_ITEM_SET_GENERATED(item);
15170                                 }
15171                                 /* QUERY_FS_INFORMATION */
15172                                 if(t2i && t2i->subcmd==0x0003){
15173                                         item=proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
15174                                         PROTO_ITEM_SET_GENERATED(item);
15175                                 }
15176
15177                                 if (t2i && check_col(pinfo->cinfo, COL_INFO)) {
15178                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
15179                                                 val_to_str(t2i->subcmd,
15180                                                         trans2_cmd_vals,
15181                                                         "<unknown (0x%02x)>"));
15182                                 }
15183                         }
15184                 }
15185                 break;
15186         }
15187
15188         WORD_COUNT;
15189
15190         /* total param count, only a 16bit integer here */
15191         tp = tvb_get_letohs(tvb, offset);
15192         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
15193         offset += 2;
15194
15195         /* total data count, only a 16 bit integer here */
15196         td = tvb_get_letohs(tvb, offset);
15197         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
15198         offset += 2;
15199
15200         /* 2 reserved bytes */
15201         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
15202         offset += 2;
15203
15204         /* param count */
15205         pc = tvb_get_letohs(tvb, offset);
15206         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
15207         offset += 2;
15208
15209         /* param offset */
15210         po = tvb_get_letohs(tvb, offset);
15211         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
15212         offset += 2;
15213
15214         /* param disp */
15215         pd = tvb_get_letohs(tvb, offset);
15216         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
15217         offset += 2;
15218
15219         /* data count */
15220         dc = tvb_get_letohs(tvb, offset);
15221         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
15222         offset += 2;
15223
15224         /* data offset */
15225         od = tvb_get_letohs(tvb, offset);
15226         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
15227         offset += 2;
15228
15229         /* data disp */
15230         dd = tvb_get_letohs(tvb, offset);
15231         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
15232         offset += 2;
15233
15234         /* setup count */
15235         sc = tvb_get_guint8(tvb, offset);
15236         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
15237         offset += 1;
15238
15239         /* reserved byte */
15240         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
15241         offset += 1;
15242
15243
15244         /* if there were any setup bytes, put them in a tvb for later */
15245         if(sc){
15246                 if((2*sc)>tvb_length_remaining(tvb, offset)){
15247                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
15248                 } else {
15249                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
15250                 }
15251                 sp_tvb = tvb_new_subset_remaining(tvb, offset);
15252         } else {
15253                 s_tvb = NULL;
15254                 sp_tvb=NULL;
15255         }
15256         offset += 2*sc;
15257
15258
15259         BYTE_COUNT;
15260
15261
15262         /* reassembly of SMB Transaction data payload.
15263            In this section we do reassembly of both the data and parameters
15264            blocks of the SMB transaction command.
15265         */
15266         save_fragmented = pinfo->fragmented;
15267         /* do we need reassembly? */
15268         if( (td!=dc) || (tp!=pc) ){
15269                 /* oh yeah, either data or parameter section needs
15270                    reassembly
15271                 */
15272                 pinfo->fragmented = TRUE;
15273                 if(smb_trans_reassembly){
15274                         /* ...and we were told to do reassembly */
15275                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
15276                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15277                                                              po, pc, pd, td+tp);
15278
15279                         }
15280                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
15281                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15282                                                              od, dc, dd+tp, td+tp);
15283                         }
15284                 }
15285         }
15286
15287         /* if we got a reassembled fd structure from the reassembly routine we must
15288            create pd_tvb from it
15289         */
15290         if(r_fd){
15291         proto_item *frag_tree_item;
15292
15293                 pd_tvb = tvb_new_child_real_data(tvb, r_fd->data, r_fd->datalen,
15294                                              r_fd->datalen);
15295                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
15296                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
15297         }
15298
15299
15300         if(pd_tvb){
15301                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
15302                 if(tp){
15303                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
15304                 }
15305                 if(td){
15306                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
15307                 }
15308         } else {
15309                 /* It was not reassembled. Do as best as we can.
15310                  * in this case we always try to dissect the stuff if
15311                  * data and param displacement is 0. i.e. for the first
15312                  * (and maybe only) packet.
15313                  */
15314                 if( (pd==0) && (dd==0) ){
15315                         int min;
15316                         int reported_min;
15317                         min = MIN(pc,tvb_length_remaining(tvb,po));
15318                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
15319                         if(min && reported_min) {
15320                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
15321                         }
15322                         min = MIN(dc,tvb_length_remaining(tvb,od));
15323                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
15324                         if(min && reported_min) {
15325                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
15326                         }
15327                         /*
15328                          * A tvbuff containing the parameters
15329                          * and the data.
15330                          * XXX - check pc and dc as well?
15331                          */
15332                         if (tvb_length_remaining(tvb, po)){
15333                                 pd_tvb = tvb_new_subset_remaining(tvb, po);
15334                         }
15335                 }
15336         }
15337
15338
15339
15340         /* parameters */
15341         if(po>offset){
15342                 /* We have some padding bytes.
15343                 */
15344                 padcnt = po-offset;
15345                 if (padcnt > bc)
15346                         padcnt = bc;
15347                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15348                 COUNT_BYTES(padcnt);
15349         }
15350         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
15351                 /* TRANSACTION2 parameters*/
15352                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
15353         }
15354         COUNT_BYTES(pc);
15355
15356
15357         /* data */
15358         if(od>offset){
15359                 /* We have some initial padding bytes.
15360                 */
15361                 padcnt = od-offset;
15362                 if (padcnt > bc)
15363                         padcnt = bc;
15364                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15365                 COUNT_BYTES(padcnt);
15366         }
15367         /*
15368          * If the data count is bigger than the count of bytes
15369          * remaining, clamp it so that the count of bytes remaining
15370          * doesn't go negative.
15371          */
15372         if (dc > bc)
15373                 dc = bc;
15374         COUNT_BYTES(dc);
15375
15376
15377
15378         /* from now on, everything is in separate tvbuffs so we dont count
15379            the bytes with COUNT_BYTES any more.
15380            neither do we reference offset any more (which by now points to the
15381            first byte AFTER this PDU */
15382
15383
15384         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
15385                 /* TRANSACTION2 parameters*/
15386                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
15387         }
15388
15389
15390         if(si->cmd==SMB_COM_TRANSACTION){
15391                 smb_transact_info_t *tri;
15392
15393                 dissected_trans = FALSE;
15394                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_TRI)
15395                         tri = si->sip->extra_info;
15396                 else
15397                         tri = NULL;
15398                 if (tri != NULL) {
15399                         switch(tri->subcmd){
15400
15401                         case TRANSACTION_PIPE:
15402                                 /* This function is safe to call for
15403                                    s_tvb==sp_tvb==NULL, i.e. if we don't
15404                                    know them at this point.
15405                                    It's also safe to call if "p_tvb"
15406                                    or "d_tvb" are null.
15407                                 */
15408                                 if( pd_tvb) {
15409                                         dissected_trans = dissect_pipe_smb(
15410                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
15411                                                 d_tvb, NULL, pinfo, top_tree);
15412                                 }
15413                                 break;
15414
15415                         case TRANSACTION_MAILSLOT:
15416                                 /* This one should be safe to call
15417                                    even if s_tvb and sp_tvb is NULL
15418                                 */
15419                                 if(d_tvb){
15420                                         dissected_trans = dissect_mailslot_smb(
15421                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
15422                                                 top_tree);
15423                                 }
15424                                 break;
15425                         }
15426                 }
15427                 if (!dissected_trans) {
15428                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
15429                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
15430                 }
15431         }
15432
15433
15434         if( (p_tvb==0) && (d_tvb==0) ){
15435                 if(check_col(pinfo->cinfo, COL_INFO)){
15436                         col_append_str(pinfo->cinfo, COL_INFO,
15437                                        "[transact continuation]");
15438                 }
15439         }
15440
15441         pinfo->fragmented = save_fragmented;
15442         END_OF_SMB
15443
15444         return offset;
15445 }
15446
15447
15448 static int
15449 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15450 {
15451         guint8 wc;
15452         guint16 bc;
15453
15454         WORD_COUNT;
15455
15456         /* Monitor handle */
15457         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
15458         offset += 2;
15459
15460         BYTE_COUNT;
15461
15462         END_OF_SMB
15463
15464         return offset;
15465 }
15466
15467 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15468    END Transaction/Transaction2 Primary and secondary requests
15469    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15470
15471
15472 static int
15473 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15474 {
15475         guint8 wc;
15476         guint16 bc;
15477
15478         WORD_COUNT;
15479
15480         if (wc != 0) {
15481                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
15482                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
15483                 offset += wc*2;
15484         }
15485
15486         BYTE_COUNT;
15487
15488         if (bc != 0) {
15489                 tvb_ensure_bytes_exist(tvb, offset, bc);
15490                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
15491                 offset += bc;
15492                 bc = 0;
15493         }
15494
15495         END_OF_SMB
15496
15497         return offset;
15498 }
15499
15500 typedef struct _smb_function {
15501        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15502        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15503 } smb_function;
15504
15505 static smb_function smb_dissector[256] = {
15506   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
15507   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
15508   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
15509   /* 0x03 Create File*/  {dissect_create_file_request, dissect_create_file_response},
15510   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
15511   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
15512   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
15513   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_rename_file_response},
15514   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
15515   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
15516   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
15517   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
15518   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
15519   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
15520   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
15521   /* 0x0f Create New*/  {dissect_create_file_request, dissect_create_new_response},
15522
15523   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
15524   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
15525   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
15526   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
15527   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
15528   /* 0x15 */  {dissect_unknown, dissect_unknown},
15529   /* 0x16 */  {dissect_unknown, dissect_unknown},
15530   /* 0x17 */  {dissect_unknown, dissect_unknown},
15531   /* 0x18 */  {dissect_unknown, dissect_unknown},
15532   /* 0x19 */  {dissect_unknown, dissect_unknown},
15533   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
15534   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
15535   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
15536   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
15537   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
15538   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
15539
15540   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
15541   /* 0x21 */  {dissect_unknown, dissect_unknown},
15542   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
15543   /* 0x23 Query Info2*/  {dissect_query_information2_request, dissect_query_information2_response},
15544   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
15545   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
15546   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15547   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
15548   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
15549   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
15550   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
15551   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
15552   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
15553   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
15554   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
15555   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
15556
15557   /* 0x30 */  {dissect_unknown, dissect_unknown},
15558   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
15559   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
15560   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15561   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
15562   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
15563   /* 0x36 */  {dissect_unknown, dissect_unknown},
15564   /* 0x37 */  {dissect_unknown, dissect_unknown},
15565   /* 0x38 */  {dissect_unknown, dissect_unknown},
15566   /* 0x39 */  {dissect_unknown, dissect_unknown},
15567   /* 0x3a */  {dissect_unknown, dissect_unknown},
15568   /* 0x3b */  {dissect_unknown, dissect_unknown},
15569   /* 0x3c */  {dissect_unknown, dissect_unknown},
15570   /* 0x3d */  {dissect_unknown, dissect_unknown},
15571   /* 0x3e */  {dissect_unknown, dissect_unknown},
15572   /* 0x3f */  {dissect_unknown, dissect_unknown},
15573
15574   /* 0x40 */  {dissect_unknown, dissect_unknown},
15575   /* 0x41 */  {dissect_unknown, dissect_unknown},
15576   /* 0x42 */  {dissect_unknown, dissect_unknown},
15577   /* 0x43 */  {dissect_unknown, dissect_unknown},
15578   /* 0x44 */  {dissect_unknown, dissect_unknown},
15579   /* 0x45 */  {dissect_unknown, dissect_unknown},
15580   /* 0x46 */  {dissect_unknown, dissect_unknown},
15581   /* 0x47 */  {dissect_unknown, dissect_unknown},
15582   /* 0x48 */  {dissect_unknown, dissect_unknown},
15583   /* 0x49 */  {dissect_unknown, dissect_unknown},
15584   /* 0x4a */  {dissect_unknown, dissect_unknown},
15585   /* 0x4b */  {dissect_unknown, dissect_unknown},
15586   /* 0x4c */  {dissect_unknown, dissect_unknown},
15587   /* 0x4d */  {dissect_unknown, dissect_unknown},
15588   /* 0x4e */  {dissect_unknown, dissect_unknown},
15589   /* 0x4f */  {dissect_unknown, dissect_unknown},
15590
15591   /* 0x50 */  {dissect_unknown, dissect_unknown},
15592   /* 0x51 */  {dissect_unknown, dissect_unknown},
15593   /* 0x52 */  {dissect_unknown, dissect_unknown},
15594   /* 0x53 */  {dissect_unknown, dissect_unknown},
15595   /* 0x54 */  {dissect_unknown, dissect_unknown},
15596   /* 0x55 */  {dissect_unknown, dissect_unknown},
15597   /* 0x56 */  {dissect_unknown, dissect_unknown},
15598   /* 0x57 */  {dissect_unknown, dissect_unknown},
15599   /* 0x58 */  {dissect_unknown, dissect_unknown},
15600   /* 0x59 */  {dissect_unknown, dissect_unknown},
15601   /* 0x5a */  {dissect_unknown, dissect_unknown},
15602   /* 0x5b */  {dissect_unknown, dissect_unknown},
15603   /* 0x5c */  {dissect_unknown, dissect_unknown},
15604   /* 0x5d */  {dissect_unknown, dissect_unknown},
15605   /* 0x5e */  {dissect_unknown, dissect_unknown},
15606   /* 0x5f */  {dissect_unknown, dissect_unknown},
15607
15608   /* 0x60 */  {dissect_unknown, dissect_unknown},
15609   /* 0x61 */  {dissect_unknown, dissect_unknown},
15610   /* 0x62 */  {dissect_unknown, dissect_unknown},
15611   /* 0x63 */  {dissect_unknown, dissect_unknown},
15612   /* 0x64 */  {dissect_unknown, dissect_unknown},
15613   /* 0x65 */  {dissect_unknown, dissect_unknown},
15614   /* 0x66 */  {dissect_unknown, dissect_unknown},
15615   /* 0x67 */  {dissect_unknown, dissect_unknown},
15616   /* 0x68 */  {dissect_unknown, dissect_unknown},
15617   /* 0x69 */  {dissect_unknown, dissect_unknown},
15618   /* 0x6a */  {dissect_unknown, dissect_unknown},
15619   /* 0x6b */  {dissect_unknown, dissect_unknown},
15620   /* 0x6c */  {dissect_unknown, dissect_unknown},
15621   /* 0x6d */  {dissect_unknown, dissect_unknown},
15622   /* 0x6e */  {dissect_unknown, dissect_unknown},
15623   /* 0x6f */  {dissect_unknown, dissect_unknown},
15624
15625   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
15626   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
15627   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
15628   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
15629   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
15630   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
15631   /* 0x76 */  {dissect_unknown, dissect_unknown},
15632   /* 0x77 */  {dissect_unknown, dissect_unknown},
15633   /* 0x78 */  {dissect_unknown, dissect_unknown},
15634   /* 0x79 */  {dissect_unknown, dissect_unknown},
15635   /* 0x7a */  {dissect_unknown, dissect_unknown},
15636   /* 0x7b */  {dissect_unknown, dissect_unknown},
15637   /* 0x7c */  {dissect_unknown, dissect_unknown},
15638   /* 0x7d */  {dissect_unknown, dissect_unknown},
15639   /* 0x7e */  {dissect_unknown, dissect_unknown},
15640   /* 0x7f */  {dissect_unknown, dissect_unknown},
15641
15642   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
15643   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
15644   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
15645   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
15646   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
15647   /* 0x85 */  {dissect_unknown, dissect_unknown},
15648   /* 0x86 */  {dissect_unknown, dissect_unknown},
15649   /* 0x87 */  {dissect_unknown, dissect_unknown},
15650   /* 0x88 */  {dissect_unknown, dissect_unknown},
15651   /* 0x89 */  {dissect_unknown, dissect_unknown},
15652   /* 0x8a */  {dissect_unknown, dissect_unknown},
15653   /* 0x8b */  {dissect_unknown, dissect_unknown},
15654   /* 0x8c */  {dissect_unknown, dissect_unknown},
15655   /* 0x8d */  {dissect_unknown, dissect_unknown},
15656   /* 0x8e */  {dissect_unknown, dissect_unknown},
15657   /* 0x8f */  {dissect_unknown, dissect_unknown},
15658
15659   /* 0x90 */  {dissect_unknown, dissect_unknown},
15660   /* 0x91 */  {dissect_unknown, dissect_unknown},
15661   /* 0x92 */  {dissect_unknown, dissect_unknown},
15662   /* 0x93 */  {dissect_unknown, dissect_unknown},
15663   /* 0x94 */  {dissect_unknown, dissect_unknown},
15664   /* 0x95 */  {dissect_unknown, dissect_unknown},
15665   /* 0x96 */  {dissect_unknown, dissect_unknown},
15666   /* 0x97 */  {dissect_unknown, dissect_unknown},
15667   /* 0x98 */  {dissect_unknown, dissect_unknown},
15668   /* 0x99 */  {dissect_unknown, dissect_unknown},
15669   /* 0x9a */  {dissect_unknown, dissect_unknown},
15670   /* 0x9b */  {dissect_unknown, dissect_unknown},
15671   /* 0x9c */  {dissect_unknown, dissect_unknown},
15672   /* 0x9d */  {dissect_unknown, dissect_unknown},
15673   /* 0x9e */  {dissect_unknown, dissect_unknown},
15674   /* 0x9f */  {dissect_unknown, dissect_unknown},
15675
15676   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
15677   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
15678   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
15679   /* 0xa3 */  {dissect_unknown, dissect_unknown},
15680   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
15681   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
15682   /* 0xa6 */  {dissect_unknown, dissect_unknown},
15683   /* 0xa7 */  {dissect_unknown, dissect_unknown},
15684   /* 0xa8 */  {dissect_unknown, dissect_unknown},
15685   /* 0xa9 */  {dissect_unknown, dissect_unknown},
15686   /* 0xaa */  {dissect_unknown, dissect_unknown},
15687   /* 0xab */  {dissect_unknown, dissect_unknown},
15688   /* 0xac */  {dissect_unknown, dissect_unknown},
15689   /* 0xad */  {dissect_unknown, dissect_unknown},
15690   /* 0xae */  {dissect_unknown, dissect_unknown},
15691   /* 0xaf */  {dissect_unknown, dissect_unknown},
15692
15693   /* 0xb0 */  {dissect_unknown, dissect_unknown},
15694   /* 0xb1 */  {dissect_unknown, dissect_unknown},
15695   /* 0xb2 */  {dissect_unknown, dissect_unknown},
15696   /* 0xb3 */  {dissect_unknown, dissect_unknown},
15697   /* 0xb4 */  {dissect_unknown, dissect_unknown},
15698   /* 0xb5 */  {dissect_unknown, dissect_unknown},
15699   /* 0xb6 */  {dissect_unknown, dissect_unknown},
15700   /* 0xb7 */  {dissect_unknown, dissect_unknown},
15701   /* 0xb8 */  {dissect_unknown, dissect_unknown},
15702   /* 0xb9 */  {dissect_unknown, dissect_unknown},
15703   /* 0xba */  {dissect_unknown, dissect_unknown},
15704   /* 0xbb */  {dissect_unknown, dissect_unknown},
15705   /* 0xbc */  {dissect_unknown, dissect_unknown},
15706   /* 0xbd */  {dissect_unknown, dissect_unknown},
15707   /* 0xbe */  {dissect_unknown, dissect_unknown},
15708   /* 0xbf */  {dissect_unknown, dissect_unknown},
15709
15710   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_open_print_file_response},
15711   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
15712   /* 0xc2 Close Print File*/  {dissect_close_print_file_request, dissect_empty},
15713   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
15714   /* 0xc4 */  {dissect_unknown, dissect_unknown},
15715   /* 0xc5 */  {dissect_unknown, dissect_unknown},
15716   /* 0xc6 */  {dissect_unknown, dissect_unknown},
15717   /* 0xc7 */  {dissect_unknown, dissect_unknown},
15718   /* 0xc8 */  {dissect_unknown, dissect_unknown},
15719   /* 0xc9 */  {dissect_unknown, dissect_unknown},
15720   /* 0xca */  {dissect_unknown, dissect_unknown},
15721   /* 0xcb */  {dissect_unknown, dissect_unknown},
15722   /* 0xcc */  {dissect_unknown, dissect_unknown},
15723   /* 0xcd */  {dissect_unknown, dissect_unknown},
15724   /* 0xce */  {dissect_unknown, dissect_unknown},
15725   /* 0xcf */  {dissect_unknown, dissect_unknown},
15726
15727   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
15728   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
15729   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
15730   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
15731   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
15732   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
15733   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
15734   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
15735   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
15736   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
15737   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
15738   /* 0xdb */  {dissect_unknown, dissect_unknown},
15739   /* 0xdc */  {dissect_unknown, dissect_unknown},
15740   /* 0xdd */  {dissect_unknown, dissect_unknown},
15741   /* 0xde */  {dissect_unknown, dissect_unknown},
15742   /* 0xdf */  {dissect_unknown, dissect_unknown},
15743
15744   /* 0xe0 */  {dissect_unknown, dissect_unknown},
15745   /* 0xe1 */  {dissect_unknown, dissect_unknown},
15746   /* 0xe2 */  {dissect_unknown, dissect_unknown},
15747   /* 0xe3 */  {dissect_unknown, dissect_unknown},
15748   /* 0xe4 */  {dissect_unknown, dissect_unknown},
15749   /* 0xe5 */  {dissect_unknown, dissect_unknown},
15750   /* 0xe6 */  {dissect_unknown, dissect_unknown},
15751   /* 0xe7 */  {dissect_unknown, dissect_unknown},
15752   /* 0xe8 */  {dissect_unknown, dissect_unknown},
15753   /* 0xe9 */  {dissect_unknown, dissect_unknown},
15754   /* 0xea */  {dissect_unknown, dissect_unknown},
15755   /* 0xeb */  {dissect_unknown, dissect_unknown},
15756   /* 0xec */  {dissect_unknown, dissect_unknown},
15757   /* 0xed */  {dissect_unknown, dissect_unknown},
15758   /* 0xee */  {dissect_unknown, dissect_unknown},
15759   /* 0xef */  {dissect_unknown, dissect_unknown},
15760
15761   /* 0xf0 */  {dissect_unknown, dissect_unknown},
15762   /* 0xf1 */  {dissect_unknown, dissect_unknown},
15763   /* 0xf2 */  {dissect_unknown, dissect_unknown},
15764   /* 0xf3 */  {dissect_unknown, dissect_unknown},
15765   /* 0xf4 */  {dissect_unknown, dissect_unknown},
15766   /* 0xf5 */  {dissect_unknown, dissect_unknown},
15767   /* 0xf6 */  {dissect_unknown, dissect_unknown},
15768   /* 0xf7 */  {dissect_unknown, dissect_unknown},
15769   /* 0xf8 */  {dissect_unknown, dissect_unknown},
15770   /* 0xf9 */  {dissect_unknown, dissect_unknown},
15771   /* 0xfa */  {dissect_unknown, dissect_unknown},
15772   /* 0xfb */  {dissect_unknown, dissect_unknown},
15773   /* 0xfc */  {dissect_unknown, dissect_unknown},
15774   /* 0xfd */  {dissect_unknown, dissect_unknown},
15775   /* 0xfe */  {dissect_unknown, dissect_unknown},
15776   /* 0xff */  {dissect_unknown, dissect_unknown},
15777 };
15778
15779 static int
15780 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
15781 {
15782         smb_info_t *si;
15783         smb_saved_info_t *sip;
15784
15785         si = pinfo->private_data;
15786         DISSECTOR_ASSERT(si);
15787
15788         if(cmd!=0xff){
15789                 proto_item *cmd_item;
15790                 proto_tree *cmd_tree;
15791                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15792
15793                 if (check_col(pinfo->cinfo, COL_INFO)) {
15794                         if(first_pdu){
15795                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15796                                         "%s %s",
15797                                         decode_smb_name(cmd),
15798                                         (si->request)? "Request" : "Response");
15799                         } else {
15800                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15801                                         "; %s",
15802                                         decode_smb_name(cmd));
15803                         }
15804
15805                 }
15806
15807                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
15808                         "%s %s (0x%02x)",
15809                         decode_smb_name(cmd),
15810                         (si->request)?"Request":"Response",
15811                         cmd);
15812
15813                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
15814
15815                 /* we track FIDs on a per transaction basis.
15816                    if this was a request and the fid was seen in a reply
15817                    we add a "generated" fid tree for this pdu and v.v.
15818                  */
15819                 sip = si->sip;
15820                 if (sip && sip->fid) {
15821                         if( (si->request && (!sip->fid_seen_in_request))
15822                           ||((!si->request) && sip->fid_seen_in_request) ){
15823                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
15824                         }
15825                 }
15826
15827                 dissector = (si->request)?
15828                         smb_dissector[cmd].request:smb_dissector[cmd].response;
15829
15830                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
15831                 proto_item_set_end(cmd_item, tvb, offset);
15832         }
15833         return offset;
15834 }
15835
15836
15837 /* NOTE: this value_string array will also be used to access data directly by
15838  * index instead of val_to_str() since
15839  * 1, the array will always span every value from 0x00 to 0xff and
15840  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
15841  * This means that this value_string array MUST always
15842  * 1, contain all entries 0x00 to 0xff
15843  * 2, all entries must be in order.
15844  */
15845 const value_string smb_cmd_vals[] = {
15846   { 0x00, "Create Directory" },
15847   { 0x01, "Delete Directory" },
15848   { 0x02, "Open" },
15849   { 0x03, "Create" },
15850   { 0x04, "Close" },
15851   { 0x05, "Flush" },
15852   { 0x06, "Delete" },
15853   { 0x07, "Rename" },
15854   { 0x08, "Query Information" },
15855   { 0x09, "Set Information" },
15856   { 0x0A, "Read" },
15857   { 0x0B, "Write" },
15858   { 0x0C, "Lock Byte Range" },
15859   { 0x0D, "Unlock Byte Range" },
15860   { 0x0E, "Create Temp" },
15861   { 0x0F, "Create New" },
15862   { 0x10, "Check Directory" },
15863   { 0x11, "Process Exit" },
15864   { 0x12, "Seek" },
15865   { 0x13, "Lock And Read" },
15866   { 0x14, "Write And Unlock" },
15867   { 0x15, "unknown-0x15" },
15868   { 0x16, "unknown-0x16" },
15869   { 0x17, "unknown-0x17" },
15870   { 0x18, "unknown-0x18" },
15871   { 0x19, "unknown-0x19" },
15872   { 0x1A, "Read Raw" },
15873   { 0x1B, "Read MPX" },
15874   { 0x1C, "Read MPX Secondary" },
15875   { 0x1D, "Write Raw" },
15876   { 0x1E, "Write MPX" },
15877   { 0x1F, "Write MPX Secondary" },
15878   { 0x20, "Write Complete" },
15879   { 0x21, "unknown-0x21" },
15880   { 0x22, "Set Information2" },
15881   { 0x23, "Query Information2" },
15882   { 0x24, "Locking AndX" },
15883   { 0x25, "Trans" },
15884   { 0x26, "Trans Secondary" },
15885   { 0x27, "IOCTL" },
15886   { 0x28, "IOCTL Secondary" },
15887   { 0x29, "Copy" },
15888   { 0x2A, "Move" },
15889   { 0x2B, "Echo" },
15890   { 0x2C, "Write And Close" },
15891   { 0x2D, "Open AndX" },
15892   { 0x2E, "Read AndX" },
15893   { 0x2F, "Write AndX" },
15894   { 0x30, "unknown-0x30" },
15895   { 0x31, "Close And Tree Disconnect" },
15896   { 0x32, "Trans2" },
15897   { 0x33, "Trans2 Secondary" },
15898   { 0x34, "Find Close2" },
15899   { 0x35, "Find Notify Close" },
15900   { 0x36, "unknown-0x36" },
15901   { 0x37, "unknown-0x37" },
15902   { 0x38, "unknown-0x38" },
15903   { 0x39, "unknown-0x39" },
15904   { 0x3A, "unknown-0x3A" },
15905   { 0x3B, "unknown-0x3B" },
15906   { 0x3C, "unknown-0x3C" },
15907   { 0x3D, "unknown-0x3D" },
15908   { 0x3E, "unknown-0x3E" },
15909   { 0x3F, "unknown-0x3F" },
15910   { 0x40, "unknown-0x40" },
15911   { 0x41, "unknown-0x41" },
15912   { 0x42, "unknown-0x42" },
15913   { 0x43, "unknown-0x43" },
15914   { 0x44, "unknown-0x44" },
15915   { 0x45, "unknown-0x45" },
15916   { 0x46, "unknown-0x46" },
15917   { 0x47, "unknown-0x47" },
15918   { 0x48, "unknown-0x48" },
15919   { 0x49, "unknown-0x49" },
15920   { 0x4A, "unknown-0x4A" },
15921   { 0x4B, "unknown-0x4B" },
15922   { 0x4C, "unknown-0x4C" },
15923   { 0x4D, "unknown-0x4D" },
15924   { 0x4E, "unknown-0x4E" },
15925   { 0x4F, "unknown-0x4F" },
15926   { 0x50, "unknown-0x50" },
15927   { 0x51, "unknown-0x51" },
15928   { 0x52, "unknown-0x52" },
15929   { 0x53, "unknown-0x53" },
15930   { 0x54, "unknown-0x54" },
15931   { 0x55, "unknown-0x55" },
15932   { 0x56, "unknown-0x56" },
15933   { 0x57, "unknown-0x57" },
15934   { 0x58, "unknown-0x58" },
15935   { 0x59, "unknown-0x59" },
15936   { 0x5A, "unknown-0x5A" },
15937   { 0x5B, "unknown-0x5B" },
15938   { 0x5C, "unknown-0x5C" },
15939   { 0x5D, "unknown-0x5D" },
15940   { 0x5E, "unknown-0x5E" },
15941   { 0x5F, "unknown-0x5F" },
15942   { 0x60, "unknown-0x60" },
15943   { 0x61, "unknown-0x61" },
15944   { 0x62, "unknown-0x62" },
15945   { 0x63, "unknown-0x63" },
15946   { 0x64, "unknown-0x64" },
15947   { 0x65, "unknown-0x65" },
15948   { 0x66, "unknown-0x66" },
15949   { 0x67, "unknown-0x67" },
15950   { 0x68, "unknown-0x68" },
15951   { 0x69, "unknown-0x69" },
15952   { 0x6A, "unknown-0x6A" },
15953   { 0x6B, "unknown-0x6B" },
15954   { 0x6C, "unknown-0x6C" },
15955   { 0x6D, "unknown-0x6D" },
15956   { 0x6E, "unknown-0x6E" },
15957   { 0x6F, "unknown-0x6F" },
15958   { 0x70, "Tree Connect" },
15959   { 0x71, "Tree Disconnect" },
15960   { 0x72, "Negotiate Protocol" },
15961   { 0x73, "Session Setup AndX" },
15962   { 0x74, "Logoff AndX" },
15963   { 0x75, "Tree Connect AndX" },
15964   { 0x76, "unknown-0x76" },
15965   { 0x77, "unknown-0x77" },
15966   { 0x78, "unknown-0x78" },
15967   { 0x79, "unknown-0x79" },
15968   { 0x7A, "unknown-0x7A" },
15969   { 0x7B, "unknown-0x7B" },
15970   { 0x7C, "unknown-0x7C" },
15971   { 0x7D, "unknown-0x7D" },
15972   { 0x7E, "unknown-0x7E" },
15973   { 0x7F, "unknown-0x7F" },
15974   { 0x80, "Query Information Disk" },
15975   { 0x81, "Search" },
15976   { 0x82, "Find" },
15977   { 0x83, "Find Unique" },
15978   { 0x84, "Find Close" },
15979   { 0x85, "unknown-0x85" },
15980   { 0x86, "unknown-0x86" },
15981   { 0x87, "unknown-0x87" },
15982   { 0x88, "unknown-0x88" },
15983   { 0x89, "unknown-0x89" },
15984   { 0x8A, "unknown-0x8A" },
15985   { 0x8B, "unknown-0x8B" },
15986   { 0x8C, "unknown-0x8C" },
15987   { 0x8D, "unknown-0x8D" },
15988   { 0x8E, "unknown-0x8E" },
15989   { 0x8F, "unknown-0x8F" },
15990   { 0x90, "unknown-0x90" },
15991   { 0x91, "unknown-0x91" },
15992   { 0x92, "unknown-0x92" },
15993   { 0x93, "unknown-0x93" },
15994   { 0x94, "unknown-0x94" },
15995   { 0x95, "unknown-0x95" },
15996   { 0x96, "unknown-0x96" },
15997   { 0x97, "unknown-0x97" },
15998   { 0x98, "unknown-0x98" },
15999   { 0x99, "unknown-0x99" },
16000   { 0x9A, "unknown-0x9A" },
16001   { 0x9B, "unknown-0x9B" },
16002   { 0x9C, "unknown-0x9C" },
16003   { 0x9D, "unknown-0x9D" },
16004   { 0x9E, "unknown-0x9E" },
16005   { 0x9F, "unknown-0x9F" },
16006   { 0xA0, "NT Trans" },
16007   { 0xA1, "NT Trans Secondary" },
16008   { 0xA2, "NT Create AndX" },
16009   { 0xA3, "unknown-0xA3" },
16010   { 0xA4, "NT Cancel" },
16011   { 0xA5, "NT Rename" },
16012   { 0xA6, "unknown-0xA6" },
16013   { 0xA7, "unknown-0xA7" },
16014   { 0xA8, "unknown-0xA8" },
16015   { 0xA9, "unknown-0xA9" },
16016   { 0xAA, "unknown-0xAA" },
16017   { 0xAB, "unknown-0xAB" },
16018   { 0xAC, "unknown-0xAC" },
16019   { 0xAD, "unknown-0xAD" },
16020   { 0xAE, "unknown-0xAE" },
16021   { 0xAF, "unknown-0xAF" },
16022   { 0xB0, "unknown-0xB0" },
16023   { 0xB1, "unknown-0xB1" },
16024   { 0xB2, "unknown-0xB2" },
16025   { 0xB3, "unknown-0xB3" },
16026   { 0xB4, "unknown-0xB4" },
16027   { 0xB5, "unknown-0xB5" },
16028   { 0xB6, "unknown-0xB6" },
16029   { 0xB7, "unknown-0xB7" },
16030   { 0xB8, "unknown-0xB8" },
16031   { 0xB9, "unknown-0xB9" },
16032   { 0xBA, "unknown-0xBA" },
16033   { 0xBB, "unknown-0xBB" },
16034   { 0xBC, "unknown-0xBC" },
16035   { 0xBD, "unknown-0xBD" },
16036   { 0xBE, "unknown-0xBE" },
16037   { 0xBF, "unknown-0xBF" },
16038   { 0xC0, "Open Print File" },
16039   { 0xC1, "Write Print File" },
16040   { 0xC2, "Close Print File" },
16041   { 0xC3, "Get Print Queue" },
16042   { 0xC4, "unknown-0xC4" },
16043   { 0xC5, "unknown-0xC5" },
16044   { 0xC6, "unknown-0xC6" },
16045   { 0xC7, "unknown-0xC7" },
16046   { 0xC8, "unknown-0xC8" },
16047   { 0xC9, "unknown-0xC9" },
16048   { 0xCA, "unknown-0xCA" },
16049   { 0xCB, "unknown-0xCB" },
16050   { 0xCC, "unknown-0xCC" },
16051   { 0xCD, "unknown-0xCD" },
16052   { 0xCE, "unknown-0xCE" },
16053   { 0xCF, "unknown-0xCF" },
16054   { 0xD0, "Send Single Block Message" },
16055   { 0xD1, "Send Broadcast Message" },
16056   { 0xD2, "Forward User Name" },
16057   { 0xD3, "Cancel Forward" },
16058   { 0xD4, "Get Machine Name" },
16059   { 0xD5, "Send Start of Multi-block Message" },
16060   { 0xD6, "Send End of Multi-block Message" },
16061   { 0xD7, "Send Text of Multi-block Message" },
16062   { 0xD8, "SMBreadbulk" },
16063   { 0xD9, "SMBwritebulk" },
16064   { 0xDA, "SMBwritebulkdata" },
16065   { 0xDB, "unknown-0xDB" },
16066   { 0xDC, "unknown-0xDC" },
16067   { 0xDD, "unknown-0xDD" },
16068   { 0xDE, "unknown-0xDE" },
16069   { 0xDF, "unknown-0xDF" },
16070   { 0xE0, "unknown-0xE0" },
16071   { 0xE1, "unknown-0xE1" },
16072   { 0xE2, "unknown-0xE2" },
16073   { 0xE3, "unknown-0xE3" },
16074   { 0xE4, "unknown-0xE4" },
16075   { 0xE5, "unknown-0xE5" },
16076   { 0xE6, "unknown-0xE6" },
16077   { 0xE7, "unknown-0xE7" },
16078   { 0xE8, "unknown-0xE8" },
16079   { 0xE9, "unknown-0xE9" },
16080   { 0xEA, "unknown-0xEA" },
16081   { 0xEB, "unknown-0xEB" },
16082   { 0xEC, "unknown-0xEC" },
16083   { 0xED, "unknown-0xED" },
16084   { 0xEE, "unknown-0xEE" },
16085   { 0xEF, "unknown-0xEF" },
16086   { 0xF0, "unknown-0xF0" },
16087   { 0xF1, "unknown-0xF1" },
16088   { 0xF2, "unknown-0xF2" },
16089   { 0xF3, "unknown-0xF3" },
16090   { 0xF4, "unknown-0xF4" },
16091   { 0xF5, "unknown-0xF5" },
16092   { 0xF6, "unknown-0xF6" },
16093   { 0xF7, "unknown-0xF7" },
16094   { 0xF8, "unknown-0xF8" },
16095   { 0xF9, "unknown-0xF9" },
16096   { 0xFA, "unknown-0xFA" },
16097   { 0xFB, "unknown-0xFB" },
16098   { 0xFC, "unknown-0xFC" },
16099   { 0xFD, "unknown-0xFD" },
16100   { 0xFE, "SMBinvalid" },
16101   { 0xFF, "unknown-0xFF" },
16102   { 0x00, NULL },
16103 };
16104
16105 static const char *decode_smb_name(guint8 cmd)
16106 {
16107   return(smb_cmd_vals[cmd].strptr);
16108 }
16109
16110
16111
16112 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16113  * Everything TVBUFFIFIED above this line
16114  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
16115
16116
16117 static void
16118 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
16119 {
16120         conv_tables_t *ct = ctarg;
16121
16122         if (ct->unmatched)
16123                 g_hash_table_destroy(ct->unmatched);
16124         if (ct->matched)
16125                 g_hash_table_destroy(ct->matched);
16126         if (ct->tid_service)
16127                 g_hash_table_destroy(ct->tid_service);
16128         g_free(ct);
16129 }
16130
16131 static void
16132 smb_init_protocol(void)
16133 {
16134         /*
16135          * Free the hash tables attached to the conversation table
16136          * structures, and then free the list of conversation table
16137          * data structures.
16138          */
16139         if (conv_tables) {
16140                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
16141                 g_slist_free(conv_tables);
16142                 conv_tables = NULL;
16143         }
16144 }
16145
16146 static const value_string errcls_types[] = {
16147   { SMB_SUCCESS, "Success"},
16148   { SMB_ERRDOS, "DOS Error"},
16149   { SMB_ERRSRV, "Server Error"},
16150   { SMB_ERRHRD, "Hardware Error"},
16151   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
16152   { 0, NULL }
16153 };
16154
16155 /* Error codes for the ERRSRV class */
16156
16157 static const value_string SRV_errors[] = {
16158   {SMBE_error, "Non specific error code"},
16159   {SMBE_badpw, "Bad password"},
16160   {SMBE_badtype, "Reserved"},
16161   {SMBE_access, "No permissions to perform the requested operation"},
16162   {SMBE_invnid, "TID invalid"},
16163   {SMBE_invnetname, "Invalid network name. Service not found"},
16164   {SMBE_invdevice, "Invalid device"},
16165   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
16166   {SMBE_qfull, "Print queue full"},
16167   {SMBE_qtoobig, "Queued item too big"},
16168   {SMBE_qeof, "EOF on print queue dump"},
16169   {SMBE_invpfid, "Invalid print file in smb_fid"},
16170   {SMBE_smbcmd, "Unrecognised command"},
16171   {SMBE_srverror, "SMB server internal error"},
16172   {SMBE_filespecs, "Fid and pathname invalid combination"},
16173   {SMBE_badlink, "Bad link in request ???"},
16174   {SMBE_badpermits, "Access specified for a file is not valid"},
16175   {SMBE_badpid, "Bad process id in request"},
16176   {SMBE_setattrmode, "Attribute mode invalid"},
16177   {SMBE_paused, "Message server paused"},
16178   {SMBE_msgoff, "Not receiving messages"},
16179   {SMBE_noroom, "No room for message"},
16180   {SMBE_rmuns, "Too many remote usernames"},
16181   {SMBE_timeout, "Operation timed out"},
16182   {SMBE_noresource, "No resources currently available for request."},
16183   {SMBE_toomanyuids, "Too many userids"},
16184   {SMBE_baduid, "Bad userid"},
16185   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
16186   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
16187   {SMBE_contMPX, "Resume MPX mode"},
16188   {SMBE_badPW, "Bad Password???"},
16189   {SMBE_nosupport, "Operation not supported"},
16190   { 0, NULL}
16191 };
16192
16193 /* Error codes for the ERRHRD class */
16194
16195 static const value_string HRD_errors[] = {
16196   {SMBE_nowrite, "Read only media"},
16197   {SMBE_badunit, "Unknown device"},
16198   {SMBE_notready, "Drive not ready"},
16199   {SMBE_badcmd, "Unknown command"},
16200   {SMBE_data, "Data (CRC) error"},
16201   {SMBE_badreq, "Bad request structure length"},
16202   {SMBE_seek, "Seek error"},
16203   {SMBE_badmedia, "Unknown media type"},
16204   {SMBE_badsector, "Sector not found"},
16205   {SMBE_nopaper, "Printer out of paper"},
16206   {SMBE_write, "Write fault"},
16207   {SMBE_read, "Read fault"},
16208   {SMBE_general, "General failure"},
16209   {SMBE_badshare, "A open conflicts with an existing open"},
16210   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
16211   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
16212   {SMBE_FCBunavail, "No FCBs are available to process request"},
16213   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
16214   {SMBE_diskfull, "Disk full???"},
16215   {0, NULL}
16216 };
16217
16218 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
16219 {
16220
16221   switch (errcls) {
16222
16223   case SMB_SUCCESS:
16224
16225     return("No Error");   /* No error ??? */
16226
16227   case SMB_ERRDOS:
16228
16229     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
16230
16231   case SMB_ERRSRV:
16232
16233     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
16234
16235   case SMB_ERRHRD:
16236
16237     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
16238
16239   default:
16240
16241     return("Unknown error class!");
16242
16243   }
16244
16245 }
16246
16247 static const true_false_string tfs_smb_flags_lock = {
16248         "Lock&Read, Write&Unlock are supported",
16249         "Lock&Read, Write&Unlock are not supported"
16250 };
16251 static const true_false_string tfs_smb_flags_receive_buffer = {
16252         "Receive buffer has been posted",
16253         "Receive buffer has not been posted"
16254 };
16255 static const true_false_string tfs_smb_flags_caseless = {
16256         "Path names are caseless",
16257         "Path names are case sensitive"
16258 };
16259 static const true_false_string tfs_smb_flags_canon = {
16260         "Pathnames are canonicalized",
16261         "Pathnames are not canonicalized"
16262 };
16263 static const true_false_string tfs_smb_flags_oplock = {
16264         "OpLock requested/granted",
16265         "OpLock not requested/granted"
16266 };
16267 static const true_false_string tfs_smb_flags_notify = {
16268         "Notify client on all modifications",
16269         "Notify client only on open"
16270 };
16271 static const true_false_string tfs_smb_flags_response = {
16272         "Message is a response to the client/redirector",
16273         "Message is a request to the server"
16274 };
16275
16276 static int
16277 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16278 {
16279         guint8 mask;
16280         proto_item *item;
16281         proto_tree *tree;
16282
16283         mask = tvb_get_guint8(tvb, offset);
16284
16285         if(parent_tree){
16286                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16287                         "Flags: 0x%02x", mask);
16288                 tree = proto_item_add_subtree(item, ett_smb_flags);
16289
16290                 proto_tree_add_boolean(tree, hf_smb_flags_response,
16291                         tvb, offset, 1, mask);
16292                 proto_tree_add_boolean(tree, hf_smb_flags_notify,
16293                         tvb, offset, 1, mask);
16294                 proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16295                         tvb, offset, 1, mask);
16296                 proto_tree_add_boolean(tree, hf_smb_flags_canon,
16297                         tvb, offset, 1, mask);
16298                 proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16299                         tvb, offset, 1, mask);
16300                 proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16301                         tvb, offset, 1, mask);
16302                 proto_tree_add_boolean(tree, hf_smb_flags_lock,
16303                         tvb, offset, 1, mask);
16304         }
16305
16306         offset += 1;
16307         return offset;
16308 }
16309
16310
16311
16312 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16313         "Long file names are allowed in the response",
16314         "Long file names are not allowed in the response"
16315 };
16316 static const true_false_string tfs_smb_flags2_ea = {
16317         "Extended attributes are supported",
16318         "Extended attributes are not supported"
16319 };
16320 static const true_false_string tfs_smb_flags2_sec_sig = {
16321         "Security signatures are supported",
16322         "Security signatures are not supported"
16323 };
16324 static const true_false_string tfs_smb_flags2_long_names_used = {
16325         "Path names in request are long file names",
16326         "Path names in request are not long file names"
16327 };
16328 static const true_false_string tfs_smb_flags2_esn = {
16329         "Extended security negotiation is supported",
16330         "Extended security negotiation is not supported"
16331 };
16332 static const true_false_string tfs_smb_flags2_dfs = {
16333         "Resolve pathnames with Dfs",
16334         "Don't resolve pathnames with Dfs"
16335 };
16336 static const true_false_string tfs_smb_flags2_roe = {
16337         "Permit reads if execute-only",
16338         "Don't permit reads if execute-only"
16339 };
16340 static const true_false_string tfs_smb_flags2_nt_error = {
16341         "Error codes are NT error codes",
16342         "Error codes are DOS error codes"
16343 };
16344 static const true_false_string tfs_smb_flags2_string = {
16345         "Strings are Unicode",
16346         "Strings are ASCII"
16347 };
16348 static int
16349 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16350 {
16351         guint16 mask;
16352         proto_item *item;
16353         proto_tree *tree;
16354
16355         mask = tvb_get_letohs(tvb, offset);
16356
16357         if(parent_tree){
16358                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16359                         "Flags2: 0x%04x", mask);
16360                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16361
16362                 proto_tree_add_boolean(tree, hf_smb_flags2_string,
16363                         tvb, offset, 2, mask);
16364                 proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16365                         tvb, offset, 2, mask);
16366                 proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16367                         tvb, offset, 2, mask);
16368                 proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16369                         tvb, offset, 2, mask);
16370                 proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16371                         tvb, offset, 2, mask);
16372                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16373                         tvb, offset, 2, mask);
16374                 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16375                         tvb, offset, 2, mask);
16376                 proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16377                         tvb, offset, 2, mask);
16378                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16379                         tvb, offset, 2, mask);
16380         }
16381         offset += 2;
16382         return offset;
16383 }
16384
16385
16386
16387 #define SMB_FLAGS_DIRN 0x80
16388
16389
16390 static void
16391 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16392 {
16393         int offset = 0;
16394         proto_item *item = NULL, *hitem = NULL;
16395         proto_tree *tree = NULL, *htree = NULL;
16396         proto_item *tmp_item=NULL;
16397         guint8          flags;
16398         guint16         flags2;
16399         smb_info_t              *si;
16400         smb_saved_info_t *sip = NULL;
16401         smb_saved_info_key_t key;
16402         smb_saved_info_key_t *new_key;
16403         guint8 errclass = 0;
16404         guint16 errcode = 0;
16405         guint32 pid_mid;
16406         conversation_t *conversation;
16407         nstime_t t, deltat;
16408
16409         si=ep_alloc0(sizeof(smb_info_t));
16410
16411         top_tree=parent_tree;
16412
16413         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16414         col_clear(pinfo->cinfo, COL_INFO);
16415
16416         /* start off using the local variable, we will allocate a new one if we
16417            need to*/
16418         si->cmd = tvb_get_guint8(tvb, offset+4);
16419         flags = tvb_get_guint8(tvb, offset+9);
16420         /*
16421          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16422          * the direction flag appears never to be set, even for what appear
16423          * to be replies.  Do some SMB servers fail to set that flag,
16424          * under the assumption that the client knows it's a reply because
16425          * it received it?
16426          */
16427         si->request = !(flags&SMB_FLAGS_DIRN);
16428         flags2 = tvb_get_letohs(tvb, offset+10);
16429         if(flags2 & 0x8000){
16430                 si->unicode = TRUE; /* Mark them as Unicode */
16431         } else {
16432                 si->unicode = FALSE;
16433         }
16434         si->tid = tvb_get_letohs(tvb, offset+24);
16435         si->pid = tvb_get_letohs(tvb, offset+26);
16436         si->uid = tvb_get_letohs(tvb, offset+28);
16437         si->mid = tvb_get_letohs(tvb, offset+30);
16438         pid_mid = (si->pid << 16) | si->mid;
16439         si->info_level = -1;
16440         si->info_count = -1;
16441
16442         if (parent_tree) {
16443                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16444                         -1, FALSE);
16445                 tree = proto_item_add_subtree(item, ett_smb);
16446
16447                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16448                         "SMB Header");
16449
16450                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16451         }
16452
16453         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16454         offset += 4;  /* Skip the marker */
16455
16456         /* find which conversation we are part of and get the tables for that
16457            conversation*/
16458         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16459                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16460         if(!conversation){
16461                 /* OK this is a new conversation so lets create it */
16462                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16463                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16464         }
16465         /* see if we already have the smb data for this conversation */
16466         si->ct=conversation_get_proto_data(conversation, proto_smb);
16467         if(!si->ct){
16468                 /* No, not yet. create it and attach it to the conversation */
16469                 si->ct = g_malloc(sizeof(conv_tables_t));
16470
16471                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16472                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16473                         smb_saved_info_equal_matched);
16474                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16475                         smb_saved_info_equal_unmatched);
16476                 si->ct->tid_service=g_hash_table_new(
16477                         smb_saved_info_hash_unmatched,
16478                         smb_saved_info_equal_unmatched);
16479                 si->ct->raw_ntlmssp = 0;
16480
16481                 si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
16482                 si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
16483                 si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
16484                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16485         }
16486
16487         if( (si->request)
16488             &&  (si->mid==0)
16489             &&  (si->uid==0)
16490             &&  (si->pid==0)
16491             &&  (si->tid==0) ){
16492                 /* this is a broadcast SMB packet, there will not be a reply.
16493                    We dont need to do anything
16494                 */
16495                 si->unidir = TRUE;
16496         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16497                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16498                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16499                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16500                 /* Ok, we got a special request type. This request is either
16501                    an NT Cancel or a continuation relative to a real request
16502                    in an earlier packet.  In either case, we don't expect any
16503                    responses to this packet.  For continuations, any later
16504                    responses we see really just belong to the original request.
16505                    Anyway, we want to remember this packet somehow and
16506                    remember which original request it is associated with so
16507                    we can say nice things such as "This is a Cancellation to
16508                    the request in frame x", but we don't want the
16509                    request/response matching to get messed up.
16510
16511                    The only thing we do in this case is trying to find which original
16512                    request we match with and insert an entry for this "special"
16513                    request for later reference. We continue to reference the original
16514                    requests smb_saved_info_t but we dont touch it or change anything
16515                    in it.
16516                 */
16517
16518                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16519
16520                 if(!pinfo->fd->flags.visited){
16521                         /* try to find which original call we match and if we
16522                            find it add us to the matched table. Dont touch
16523                            anything else since we dont want this one to mess
16524                            up the request/response matching. We still consider
16525                            the initial call the real request and this is only
16526                            some sort of continuation.
16527                         */
16528                         /* we only check the unmatched table and assume that the
16529                            last seen MID matching ours is the right one.
16530                            This can fail but is better than nothing
16531                         */
16532                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16533                         if(sip!=NULL){
16534                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16535                                 new_key->frame = pinfo->fd->num;
16536                                 new_key->pid_mid = pid_mid;
16537                                 g_hash_table_insert(si->ct->matched, new_key,
16538                                     sip);
16539                         }
16540                 } else {
16541                         /* we have seen this packet before; check the
16542                            matching table
16543                         */
16544                         key.frame = pinfo->fd->num;
16545                         key.pid_mid = pid_mid;
16546                         sip=g_hash_table_lookup(si->ct->matched, &key);
16547                         if(sip==NULL){
16548                         /*
16549                           We didn't find it.
16550                           Too bad, unfortunately there is not really much we can
16551                           do now since this means that we never saw the initial
16552                           request.
16553                          */
16554                         }
16555                 }
16556
16557
16558                 if(sip && sip->frame_req){
16559                         switch(si->cmd){
16560                         case SMB_COM_NT_CANCEL:
16561                                 tmp_item=proto_tree_add_uint(htree, hf_smb_cancel_to,
16562                                                     tvb, 0, 0, sip->frame_req);
16563                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16564                                 break;
16565                         case SMB_COM_TRANSACTION_SECONDARY:
16566                         case SMB_COM_TRANSACTION2_SECONDARY:
16567                         case SMB_COM_NT_TRANSACT_SECONDARY:
16568                                 tmp_item=proto_tree_add_uint(htree, hf_smb_continuation_to,
16569                                                     tvb, 0, 0, sip->frame_req);
16570                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16571                                 break;
16572                         }
16573                 } else {
16574                         switch(si->cmd){
16575                         case SMB_COM_NT_CANCEL:
16576                                 proto_tree_add_text(htree, tvb, 0, 0,
16577                                                     "Cancellation to: <unknown frame>");
16578                                 break;
16579                         case SMB_COM_TRANSACTION_SECONDARY:
16580                         case SMB_COM_TRANSACTION2_SECONDARY:
16581                         case SMB_COM_NT_TRANSACT_SECONDARY:
16582                                 proto_tree_add_text(htree, tvb, 0, 0,
16583                                                     "Continuation to: <unknown frame>");
16584                                 break;
16585                         }
16586                 }
16587         } else { /* normal bidirectional request or response */
16588                 si->unidir = FALSE;
16589
16590                 if(!pinfo->fd->flags.visited){
16591                         /* first see if we find an unmatched smb "equal" to
16592                            the current one
16593                         */
16594                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16595                         if(sip!=NULL){
16596                                 gboolean cmd_match=FALSE;
16597
16598                                 /*
16599                                  * Make sure the SMB we found was the
16600                                  * same command, or a different command
16601                                  * that's another valid type of reply
16602                                  * to that command.
16603                                  */
16604                                 if(si->cmd==sip->cmd){
16605                                         cmd_match=TRUE;
16606                                 }
16607                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16608                                         cmd_match=TRUE;
16609                                 }
16610                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16611                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16612                                         cmd_match=TRUE;
16613                                 }
16614                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16615                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16616                                         cmd_match=TRUE;
16617                                 }
16618                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16619                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16620                                         cmd_match=TRUE;
16621                                 }
16622
16623                                 if( (si->request) || (!cmd_match) ) {
16624                                         /* We are processing an SMB request but there was already
16625                                            another "identical" smb request we had not matched yet.
16626                                            This must mean that either we have a retransmission or that the
16627                                            response to the previous one was lost and the client has reused
16628                                            the MID for this conversation. In either case it's not much more
16629                                            we can do than forget the old request and concentrate on the
16630                                            present one instead.
16631
16632                                            We also do this cleanup if we see that the cmd in the original
16633                                            request in sip->cmd is not compatible with the current cmd.
16634                                            This is to prevent matching errors such as if there were two
16635                                            SMBs of different cmds but with identical MID and PID values and
16636                                            if wireshark lost the first reply and the second request.
16637                                         */
16638                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16639                                         sip=NULL; /* XXX should free it as well */
16640                                 } else {
16641                                         /* we have found a response to some
16642                                            request we have seen earlier.
16643                                            What we do now depends on whether
16644                                            this is the first response to that
16645                                            request we see (id frame_res==0) or
16646                                            if it's a response to a request
16647                                            for which we've seen an earlier
16648                                            response that's continued.
16649                                         */
16650                                         if(sip->frame_res==0 ||
16651                                            sip->flags & SMB_SIF_IS_CONTINUED){
16652                                                 /* OK, it is the first response
16653                                                    we have seen to this packet,
16654                                                    or it's a continuation of
16655                                                    a response we've seen. */
16656                                                 sip->frame_res = pinfo->fd->num;
16657                                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16658                                                 new_key->frame = sip->frame_res;
16659                                                 new_key->pid_mid = pid_mid;
16660                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16661                                                 /* We remove the entry for unmatched since we have found a match.
16662                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
16663                                                  * and if there is packetloss in the trace (maybe due to large holes
16664                                                  * created by a sniffer device not being able to keep up
16665                                                  * with the line rate.
16666                                                  * There is a real possibility that the following would occur which is painful :
16667                                                  * 1, -> Request  MID:5
16668                                                  * 2, <- Response MID:5
16669                                                  *   3, ->Request  MID:5 (missing from capture)
16670                                                  * 4, <- Response MID:5
16671                                                  * We DONT want #4 to be presented as a response to #1
16672                                                  */
16673                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16674                                         } else {
16675                                                 /* We have already seen another response to this MID.
16676                                                    Since the MID in reality is only something like 10 bits
16677                                                    this probably means that we just have a MID that is being
16678                                                    reused due to the small MID space and that this is a new
16679                                                    command we did not see the original request for.
16680                                                 */
16681                                                 sip=NULL;
16682                                         }
16683                                 }
16684                         }
16685                         if(si->request){
16686                                 sip = se_alloc(sizeof(smb_saved_info_t));
16687                                 sip->frame_req = pinfo->fd->num;
16688                                 sip->frame_res = 0;
16689                                 sip->req_time = pinfo->fd->abs_ts;
16690                                 sip->flags = 0;
16691                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
16692                                     == (void *)TID_IPC) {
16693                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16694                                 }
16695                                 sip->cmd = si->cmd;
16696                                 sip->extra_info = NULL;
16697                                 sip->extra_info_type = SMB_EI_NONE;
16698                                 sip->fid=0;
16699                                 sip->fid_seen_in_request=0;
16700                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
16701                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16702                                 new_key->frame = sip->frame_req;
16703                                 new_key->pid_mid = pid_mid;
16704                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16705                         }
16706                 } else {
16707                         /* we have seen this packet before; check the
16708                            matching table.
16709                            If we haven't yet seen the reply, we won't
16710                            find the info for it; we don't need it, as
16711                            we only use it to save information, and, as
16712                            we've seen this packet before, we've already
16713                            saved the information.
16714                         */
16715                         key.frame = pinfo->fd->num;
16716                         key.pid_mid = pid_mid;
16717                         sip=g_hash_table_lookup(si->ct->matched, &key);
16718                 }
16719         }
16720
16721         /*
16722          * Pass the "sip" on to subdissectors through "si".
16723          */
16724         si->sip = sip;
16725
16726         if (sip != NULL) {
16727                 /*
16728                  * Put in fields for the frame number of the frame to which
16729                  * this is a response or the frame with the response to this
16730                  * frame - if we know the frame number (i.e., it's not 0).
16731                  */
16732                 if(si->request){
16733                         if (sip->frame_res != 0) {
16734                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16735                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16736                         }
16737                 } else {
16738                         if (sip->frame_req != 0) {
16739                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16740                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16741                                 t = pinfo->fd->abs_ts;
16742                                 nstime_delta(&deltat, &t, &sip->req_time);
16743                                 tmp_item=proto_tree_add_time(htree, hf_smb_time, tvb,
16744                                     0, 0, &deltat);
16745                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16746                         }
16747                 }
16748         }
16749
16750         /* smb command */
16751         proto_tree_add_uint_format(htree, hf_smb_cmd, tvb, offset, 1, si->cmd, "SMB Command: %s (0x%02x)", decode_smb_name(si->cmd), si->cmd);
16752         offset += 1;
16753
16754         if(flags2 & 0x4000){
16755                 /* handle NT 32 bit error code */
16756
16757                 si->nt_status = tvb_get_letohl(tvb, offset);
16758
16759                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16760                         TRUE);
16761                 offset += 4;
16762
16763         } else {
16764                 /* handle DOS error code & class */
16765                 errclass = tvb_get_guint8(tvb, offset);
16766                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16767                         errclass);
16768                 offset += 1;
16769
16770                 /* reserved byte */
16771                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16772                 offset += 1;
16773
16774                 /* error code */
16775                 /* XXX - the type of this field depends on the value of
16776                  * "errcls", so there is isn't a single value_string array
16777                  * fo it, so there can't be a single field for it.
16778                  */
16779                 errcode = tvb_get_letohs(tvb, offset);
16780                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16781                         offset, 2, errcode, "Error Code: %s",
16782                         decode_smb_error(errclass, errcode));
16783                 offset += 2;
16784         }
16785
16786         /* flags */
16787         offset = dissect_smb_flags(tvb, htree, offset);
16788
16789         /* flags2 */
16790         offset = dissect_smb_flags2(tvb, htree, offset);
16791
16792         /*
16793          * The document at
16794          *
16795          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16796          *
16797          * (a text version of "Microsoft Networks SMB FILE SHARING
16798          * PROTOCOL, Document Version 6.0p") says that:
16799          *
16800          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16801          *      the "High Part of PID";
16802          *
16803          *      the next four bytes are reserved;
16804          *
16805          *      the next four bytes are, for SMB-over-IPX (with no
16806          *      NetBIOS involved) two bytes of Session ID and two bytes
16807          *      of SequenceNumber.
16808          *
16809          * Network Monitor 2.x dissects the four bytes before the Session ID
16810          * as a "Key", and the two bytes after the SequenceNumber as
16811          * a "Group ID".
16812          *
16813          * The "High Part of PID" has been seen in calls other than NT
16814          * Create and X, although most of them appear to be I/O on DCE RPC
16815          * pipes opened with the NT Create and X in question.
16816          */
16817         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16818         offset += 2;
16819
16820         if (pinfo->ptype == PT_IPX &&
16821             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16822              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16823              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16824                 /*
16825                  * This is SMB-over-IPX.
16826                  * XXX - do we have to worry about "sequenced commands",
16827                  * as per the Samba document?  They say that for
16828                  * "unsequenced commands" (with a sequence number of 0),
16829                  * the Mid must be unique, but perhaps the Mid doesn't
16830                  * have to be unique for sequenced commands.  In at least
16831                  * one capture with SMB-over-IPX, however, the Mids
16832                  * are unique even for sequenced commands.
16833                  */
16834                 /* Key */
16835                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16836                     TRUE);
16837                 offset += 4;
16838
16839                 /* Session ID */
16840                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16841                     TRUE);
16842                 offset += 2;
16843
16844                 /* Sequence number */
16845                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16846                     TRUE);
16847                 offset += 2;
16848
16849                 /* Group ID */
16850                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16851                     TRUE);
16852                 offset += 2;
16853         } else {
16854                 /*
16855                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16856                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16857                  * bytes after the "High part of PID" are an 8-byte
16858                  * signature ...
16859                  */
16860                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16861                 offset += 8;
16862
16863                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16864                 offset += 2;
16865         }
16866
16867         pinfo->private_data = si;
16868
16869         /* TID
16870          * TreeConnectAndX(0x75) is special, here it is the mere fact of
16871          * having a response that means that the share was mapped and we
16872          * need to track it
16873          */
16874         if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
16875                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
16876         } else {
16877                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
16878         }
16879
16880         /* PID */
16881         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16882         offset += 2;
16883
16884         /* UID */
16885         offset=dissect_smb_uid(tvb, htree, offset, si);
16886
16887         /* MID */
16888         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16889         offset += 2;
16890
16891         /* tap the packet before the dissectors are called so we still get
16892            the tap listener called even if there is an exception.
16893         */
16894         tap_queue_packet(smb_tap, pinfo, si);
16895         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16896
16897         /* Append error info from this packet to info string. */
16898         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16899                 if (flags2 & 0x4000) {
16900                         /*
16901                          * The status is an NT status code; was there
16902                          * an error?
16903                          */
16904                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
16905                                 /*
16906                                  * Yes.
16907                                  */
16908                                 col_append_fstr(
16909                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16910                                         val_to_str(si->nt_status, NT_errors,
16911                                             "Unknown (0x%08X)"));
16912                         }
16913                 } else {
16914                         /*
16915                          * The status is a DOS error class and code; was
16916                          * there an error?
16917                          */
16918                         if (errclass != SMB_SUCCESS) {
16919                                 /*
16920                                  * Yes.
16921                                  */
16922                                 col_append_fstr(
16923                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16924                                         decode_smb_error(errclass, errcode));
16925                         }
16926                 }
16927         }
16928 }
16929
16930 static gboolean
16931 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16932 {
16933         /* must check that this really is a smb packet */
16934         if (tvb_length(tvb) < 4)
16935                 return FALSE;
16936
16937         if( (tvb_get_guint8(tvb, 0) != 0xff)
16938             || (tvb_get_guint8(tvb, 1) != 'S')
16939             || (tvb_get_guint8(tvb, 2) != 'M')
16940             || (tvb_get_guint8(tvb, 3) != 'B') ){
16941                 return FALSE;
16942         }
16943
16944         dissect_smb(tvb, pinfo, parent_tree);
16945         return TRUE;
16946 }
16947
16948 void
16949 proto_register_smb(void)
16950 {
16951         static hf_register_info hf[] = {
16952         { &hf_smb_cmd,
16953                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16954                 VALS(smb_cmd_vals), 0x0, NULL, HFILL }},
16955
16956         { &hf_smb_trans2_subcmd,
16957                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16958                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16959
16960         { &hf_smb_nt_trans_subcmd,
16961                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16962                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16963
16964         { &hf_smb_word_count,
16965                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16966                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16967
16968         { &hf_smb_byte_count,
16969                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16970                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16971
16972         { &hf_smb_response_to,
16973                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16974                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16975
16976         { &hf_smb_time,
16977                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16978                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16979
16980         { &hf_smb_response_in,
16981                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16982                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16983
16984         { &hf_smb_continuation_to,
16985                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16986                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16987
16988         { &hf_smb_nt_status,
16989                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16990                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16991
16992         { &hf_smb_error_class,
16993                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16994                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16995
16996         { &hf_smb_error_code,
16997                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16998                 NULL, 0, "DOS Error Code", HFILL }},
16999
17000         { &hf_smb_reserved,
17001                 { "Reserved", "smb.reserved", FT_BYTES, BASE_NONE,
17002                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
17003
17004         { &hf_smb_sig,
17005                 { "Signature", "smb.signature", FT_BYTES, BASE_NONE,
17006                 NULL, 0, "Signature bytes", HFILL }},
17007
17008         { &hf_smb_key,
17009                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
17010                 NULL, 0, "SMB-over-IPX Key", HFILL }},
17011
17012         { &hf_smb_session_id,
17013                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
17014                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
17015
17016         { &hf_smb_sequence_num,
17017                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
17018                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
17019
17020         { &hf_smb_group_id,
17021                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
17022                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
17023
17024         { &hf_smb_pid,
17025                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
17026                 NULL, 0, NULL, HFILL }},
17027
17028         { &hf_smb_pid_high,
17029                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
17030                 NULL, 0, "Process ID High Bytes", HFILL }},
17031
17032         { &hf_smb_tid,
17033                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
17034                 NULL, 0, NULL, HFILL }},
17035
17036         { &hf_smb_uid,
17037                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
17038                 NULL, 0, NULL, HFILL }},
17039
17040         { &hf_smb_mid,
17041                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
17042                 NULL, 0, NULL, HFILL }},
17043
17044         { &hf_smb_flags_lock,
17045                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
17046                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
17047
17048         { &hf_smb_flags_receive_buffer,
17049                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
17050                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
17051
17052         { &hf_smb_flags_caseless,
17053                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
17054                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
17055
17056         { &hf_smb_flags_canon,
17057                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
17058                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
17059
17060         { &hf_smb_flags_oplock,
17061                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
17062                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
17063
17064         { &hf_smb_flags_notify,
17065                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
17066                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
17067
17068         { &hf_smb_flags_response,
17069                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
17070                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
17071
17072         { &hf_smb_flags2_long_names_allowed,
17073                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
17074                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
17075
17076         { &hf_smb_flags2_ea,
17077                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
17078                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
17079
17080         { &hf_smb_flags2_sec_sig,
17081                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
17082                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
17083
17084         { &hf_smb_flags2_long_names_used,
17085                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
17086                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
17087
17088         { &hf_smb_flags2_esn,
17089                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
17090                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
17091
17092         { &hf_smb_flags2_dfs,
17093                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
17094                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
17095
17096         { &hf_smb_flags2_roe,
17097                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
17098                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
17099
17100         { &hf_smb_flags2_nt_error,
17101                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
17102                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
17103
17104         { &hf_smb_flags2_string,
17105                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
17106                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
17107
17108         { &hf_smb_buffer_format,
17109                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
17110                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
17111
17112         { &hf_smb_dialect_name,
17113                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
17114                 NULL, 0, "Name of dialect", HFILL }},
17115
17116         { &hf_smb_dialect_index,
17117                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
17118                 NULL, 0, "Index of selected dialect", HFILL }},
17119
17120         { &hf_smb_max_trans_buf_size,
17121                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
17122                 NULL, 0, "Maximum transmit buffer size", HFILL }},
17123
17124         { &hf_smb_max_mpx_count,
17125                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
17126                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
17127
17128         { &hf_smb_max_vcs_num,
17129                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
17130                 NULL, 0, "Maximum VCs between client and server", HFILL }},
17131
17132         { &hf_smb_session_key,
17133                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
17134                 NULL, 0, "Unique token identifying this session", HFILL }},
17135
17136         { &hf_smb_server_timezone,
17137                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
17138                 NULL, 0, "Current timezone at server.", HFILL }},
17139
17140         { &hf_smb_encryption_key_length,
17141                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
17142                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
17143
17144         { &hf_smb_encryption_key,
17145                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_NONE,
17146                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17147
17148         { &hf_smb_primary_domain,
17149                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17150                 NULL, 0, "The server's primary domain", HFILL }},
17151
17152         { &hf_smb_server,
17153                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17154                 NULL, 0, "The name of the DC/server", HFILL }},
17155
17156         { &hf_smb_max_raw_buf_size,
17157                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17158                 NULL, 0, "Maximum raw buffer size", HFILL }},
17159
17160         { &hf_smb_server_guid,
17161                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_NONE,
17162                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17163
17164         { &hf_smb_security_blob_len,
17165                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17166                 NULL, 0, "Security blob length", HFILL }},
17167
17168         { &hf_smb_security_blob,
17169                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_NONE,
17170                 NULL, 0, "Security blob", HFILL }},
17171
17172         { &hf_smb_sm_mode16,
17173                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17174                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17175
17176         { &hf_smb_sm_password16,
17177                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17178                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17179
17180         { &hf_smb_sm_mode,
17181                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17182                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17183
17184         { &hf_smb_sm_password,
17185                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17186                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17187
17188         { &hf_smb_sm_signatures,
17189                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17190                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17191
17192         { &hf_smb_sm_sig_required,
17193                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17194                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17195
17196         { &hf_smb_rm_read,
17197                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17198                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17199
17200         { &hf_smb_rm_write,
17201                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17202                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17203
17204         { &hf_smb_server_date_time,
17205                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17206                 NULL, 0, "Current date and time at server", HFILL }},
17207
17208         { &hf_smb_server_smb_date,
17209                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17210                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17211
17212         { &hf_smb_server_smb_time,
17213                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17214                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17215
17216         { &hf_smb_server_cap_raw_mode,
17217                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17218                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17219
17220         { &hf_smb_server_cap_mpx_mode,
17221                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17222                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17223
17224         { &hf_smb_server_cap_unicode,
17225                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17226                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17227
17228         { &hf_smb_server_cap_large_files,
17229                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17230                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17231
17232         { &hf_smb_server_cap_nt_smbs,
17233                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17234                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17235
17236         { &hf_smb_server_cap_rpc_remote_apis,
17237                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17238                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17239
17240         { &hf_smb_server_cap_nt_status,
17241                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17242                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17243
17244         { &hf_smb_server_cap_level_ii_oplocks,
17245                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17246                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17247
17248         { &hf_smb_server_cap_lock_and_read,
17249                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17250                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17251
17252         { &hf_smb_server_cap_nt_find,
17253                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17254                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17255
17256         { &hf_smb_server_cap_dfs,
17257                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17258                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17259
17260         { &hf_smb_server_cap_infolevel_passthru,
17261                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17262                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17263
17264         { &hf_smb_server_cap_large_readx,
17265                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17266                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17267
17268         { &hf_smb_server_cap_large_writex,
17269                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17270                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17271
17272         { &hf_smb_server_cap_unix,
17273                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17274                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17275
17276         { &hf_smb_server_cap_reserved,
17277                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17278                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17279
17280         { &hf_smb_server_cap_bulk_transfer,
17281                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17282                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17283
17284         { &hf_smb_server_cap_compressed_data,
17285                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17286                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17287
17288         { &hf_smb_server_cap_extended_security,
17289                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17290                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17291
17292         { &hf_smb_system_time,
17293                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17294                 NULL, 0, NULL, HFILL }},
17295
17296         { &hf_smb_unknown,
17297                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_NONE,
17298                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17299
17300         { &hf_smb_dir_name,
17301                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17302                 NULL, 0, "SMB Directory Name", HFILL }},
17303
17304         { &hf_smb_echo_count,
17305                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17306                 NULL, 0, "Number of times to echo data back", HFILL }},
17307
17308         { &hf_smb_echo_data,
17309                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_NONE,
17310                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17311
17312         { &hf_smb_echo_seq_num,
17313                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17314                 NULL, 0, "Sequence number for this echo response", HFILL }},
17315
17316         { &hf_smb_max_buf_size,
17317                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17318                 NULL, 0, "Max client buffer size", HFILL }},
17319
17320         { &hf_smb_path,
17321                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17322                 NULL, 0, "Path. Server name and share name", HFILL }},
17323
17324         { &hf_smb_service,
17325                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17326                 NULL, 0, "Service name", HFILL }},
17327
17328         { &hf_smb_password,
17329                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17330                 NULL, 0, NULL, HFILL }},
17331
17332         { &hf_smb_ansi_password,
17333                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17334                 NULL, 0, NULL, HFILL }},
17335
17336         { &hf_smb_unicode_password,
17337                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17338                 NULL, 0, NULL, HFILL }},
17339
17340         { &hf_smb_move_flags_file,
17341                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17342                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17343
17344         { &hf_smb_move_flags_dir,
17345                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17346                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17347
17348         { &hf_smb_move_flags_verify,
17349                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17350                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17351
17352         { &hf_smb_files_moved,
17353                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17354                 NULL, 0, "Number of files moved", HFILL }},
17355
17356         { &hf_smb_copy_flags_file,
17357                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17358                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17359
17360         { &hf_smb_copy_flags_dir,
17361                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17362                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17363
17364         { &hf_smb_copy_flags_dest_mode,
17365                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17366                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17367
17368         { &hf_smb_copy_flags_source_mode,
17369                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17370                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17371
17372         { &hf_smb_copy_flags_verify,
17373                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17374                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17375
17376         { &hf_smb_copy_flags_tree_copy,
17377                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17378                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17379
17380         { &hf_smb_copy_flags_ea_action,
17381                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17382                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17383
17384         { &hf_smb_count,
17385                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17386                 NULL, 0, "Count number of items/bytes", HFILL }},
17387
17388         { &hf_smb_count_low,
17389                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17390                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17391
17392         { &hf_smb_count_high,
17393                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17394                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17395
17396         { &hf_smb_file_name,
17397                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17398                 NULL, 0, NULL, HFILL }},
17399
17400         { &hf_smb_open_function_create,
17401                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17402                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17403
17404         { &hf_smb_open_function_open,
17405                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17406                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17407
17408         { &hf_smb_fid,
17409                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17410                 NULL, 0, "FID: File ID", HFILL }},
17411
17412         { &hf_smb_file_attr_read_only_16bit,
17413                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17414                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17415
17416         { &hf_smb_file_attr_read_only_8bit,
17417                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17418                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17419
17420         { &hf_smb_file_attr_hidden_16bit,
17421                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17422                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17423
17424         { &hf_smb_file_attr_hidden_8bit,
17425                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17426                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17427
17428         { &hf_smb_file_attr_system_16bit,
17429                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17430                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17431
17432         { &hf_smb_file_attr_system_8bit,
17433                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17434                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17435
17436         { &hf_smb_file_attr_volume_16bit,
17437                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17438                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17439
17440         { &hf_smb_file_attr_volume_8bit,
17441                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17442                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17443
17444         { &hf_smb_file_attr_directory_16bit,
17445                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17446                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17447
17448         { &hf_smb_file_attr_directory_8bit,
17449                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17450                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17451
17452         { &hf_smb_file_attr_archive_16bit,
17453                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17454                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17455
17456         { &hf_smb_file_attr_archive_8bit,
17457                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17458                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17459
17460         { &hf_smb_file_attr_device,
17461                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17462                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17463
17464         { &hf_smb_file_attr_normal,
17465                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17466                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17467
17468         { &hf_smb_file_attr_temporary,
17469                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17470                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17471
17472         { &hf_smb_file_attr_sparse,
17473                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17474                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17475
17476         { &hf_smb_file_attr_reparse,
17477                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17478                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17479
17480         { &hf_smb_file_attr_compressed,
17481                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17482                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17483
17484         { &hf_smb_file_attr_offline,
17485                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17486                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17487
17488         { &hf_smb_file_attr_not_content_indexed,
17489                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17490                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17491
17492         { &hf_smb_file_attr_encrypted,
17493                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17494                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17495
17496         { &hf_smb_file_size,
17497                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17498                 NULL, 0, NULL, HFILL }},
17499
17500         { &hf_smb_search_attribute_read_only,
17501                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17502                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17503
17504         { &hf_smb_search_attribute_hidden,
17505                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17506                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17507
17508         { &hf_smb_search_attribute_system,
17509                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17510                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17511
17512         { &hf_smb_search_attribute_volume,
17513                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17514                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17515
17516         { &hf_smb_search_attribute_directory,
17517                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17518                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17519
17520         { &hf_smb_search_attribute_archive,
17521                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17522                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17523
17524         { &hf_smb_access_mode,
17525                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17526                 VALS(da_access_vals), 0x0007, NULL, HFILL }},
17527
17528         { &hf_smb_access_sharing,
17529                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17530                 VALS(da_sharing_vals), 0x0070, NULL, HFILL }},
17531
17532         { &hf_smb_access_locality,
17533                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17534                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17535
17536         { &hf_smb_access_caching,
17537                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17538                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17539
17540         { &hf_smb_access_writetru,
17541                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17542                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17543
17544         { &hf_smb_create_time,
17545                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17546                 NULL, 0, "Creation Time", HFILL }},
17547
17548         { &hf_smb_modify_time,
17549                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17550                   NULL, 0, "Modification Time", HFILL }},
17551
17552         { &hf_smb_backup_time,
17553                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17554                   NULL, 0, "Backup time", HFILL}},
17555
17556         { &hf_smb_mac_alloc_block_count,
17557                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17558                   NULL, 0, NULL, HFILL}},
17559
17560         { &hf_smb_mac_alloc_block_size,
17561                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17562                   NULL, 0, "Allocation Block Size", HFILL}},
17563
17564         { &hf_smb_mac_free_block_count,
17565                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17566                   NULL, 0, NULL, HFILL}},
17567
17568         { &hf_smb_mac_root_file_count,
17569                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17570                 NULL, 0, NULL, HFILL}},
17571
17572         { &hf_smb_mac_root_dir_count,
17573           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17574             NULL, 0, NULL, HFILL}},
17575
17576         { &hf_smb_mac_file_count,
17577           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17578             NULL, 0, "File Count", HFILL}},
17579
17580         { &hf_smb_mac_dir_count,
17581           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17582             NULL, 0, "Directory Count", HFILL}},
17583
17584         { &hf_smb_mac_support_flags,
17585           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17586             NULL, 0, NULL, HFILL}},
17587
17588         { &hf_smb_mac_sup_access_ctrl,
17589           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17590             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17591
17592         { &hf_smb_mac_sup_getset_comments,
17593           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17594             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17595
17596         { &hf_smb_mac_sup_desktopdb_calls,
17597           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17598             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17599
17600         { &hf_smb_mac_sup_unique_ids,
17601           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17602             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17603
17604         { &hf_smb_mac_sup_streams,
17605           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17606             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17607
17608         { &hf_smb_create_dos_date,
17609                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17610                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17611
17612         { &hf_smb_create_dos_time,
17613                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17614                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17615
17616         { &hf_smb_last_write_time,
17617                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17618                 NULL, 0, "Time this file was last written to", HFILL }},
17619
17620         { &hf_smb_last_write_dos_date,
17621                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17622                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17623
17624         { &hf_smb_last_write_dos_time,
17625                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17626                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17627
17628         { &hf_smb_old_file_name,
17629                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
17630                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17631
17632         { &hf_smb_offset,
17633                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17634                 NULL, 0, "Offset in file", HFILL }},
17635
17636         { &hf_smb_remaining,
17637                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17638                 NULL, 0, "Remaining number of bytes", HFILL }},
17639
17640         { &hf_smb_padding,
17641                 { "Padding", "smb.padding", FT_BYTES, BASE_NONE,
17642                 NULL, 0, "Padding or unknown data", HFILL }},
17643
17644         { &hf_smb_file_data,
17645                 { "File Data", "smb.file_data", FT_BYTES, BASE_NONE,
17646                 NULL, 0, "Data read/written to the file", HFILL }},
17647
17648         { &hf_smb_mac_fndrinfo,
17649                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_NONE,
17650                   NULL, 0, NULL, HFILL}},
17651
17652         { &hf_smb_total_data_len,
17653                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17654                 NULL, 0, "Total length of data", HFILL }},
17655
17656         { &hf_smb_data_len,
17657                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17658                 NULL, 0, "Length of data", HFILL }},
17659
17660         { &hf_smb_data_len_low,
17661                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17662                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17663
17664         { &hf_smb_data_len_high,
17665                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17666                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17667
17668         { &hf_smb_seek_mode,
17669                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17670                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17671
17672         { &hf_smb_access_time,
17673                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17674                 NULL, 0, "Last Access Time", HFILL }},
17675
17676         { &hf_smb_access_dos_date,
17677                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17678                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17679
17680         { &hf_smb_access_dos_time,
17681                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17682                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17683
17684         { &hf_smb_data_size,
17685                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17686                 NULL, 0, NULL, HFILL }},
17687
17688         { &hf_smb_alloc_size,
17689                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17690                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17691
17692         { &hf_smb_max_count,
17693                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17694                 NULL, 0, "Maximum Count", HFILL }},
17695
17696         { &hf_smb_max_count_low,
17697                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17698                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17699
17700         { &hf_smb_max_count_high,
17701                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17702                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17703
17704         { &hf_smb_min_count,
17705                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17706                 NULL, 0, "Minimum Count", HFILL }},
17707
17708         { &hf_smb_timeout,
17709                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17710                 NULL, 0, "Timeout in miliseconds", HFILL }},
17711
17712         { &hf_smb_high_offset,
17713                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17714                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17715
17716         { &hf_smb_units,
17717                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17718                 NULL, 0, "Total number of units at server", HFILL }},
17719
17720         { &hf_smb_bpu,
17721                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17722                 NULL, 0, "Blocks per unit at server", HFILL }},
17723
17724         { &hf_smb_blocksize,
17725                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17726                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17727
17728         { &hf_smb_freeunits,
17729                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17730                 NULL, 0, "Number of free units at server", HFILL }},
17731
17732         { &hf_smb_data_offset,
17733                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17734                 NULL, 0, NULL, HFILL }},
17735
17736         { &hf_smb_dcm,
17737                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17738                 NULL, 0, NULL, HFILL }},
17739
17740         { &hf_smb_request_mask,
17741                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17742                 NULL, 0, "Connectionless mode mask", HFILL }},
17743
17744         { &hf_smb_response_mask,
17745                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17746                 NULL, 0, "Connectionless mode mask", HFILL }},
17747
17748         { &hf_smb_search_id,
17749                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17750                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17751
17752         { &hf_smb_write_mode_write_through,
17753                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17754                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17755
17756         { &hf_smb_write_mode_return_remaining,
17757                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17758                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17759
17760         { &hf_smb_write_mode_raw,
17761                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17762                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17763
17764         { &hf_smb_write_mode_message_start,
17765                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17766                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17767
17768         { &hf_smb_write_mode_connectionless,
17769                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17770                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17771
17772         { &hf_smb_resume_key_len,
17773                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17774                 NULL, 0, "Resume Key length", HFILL }},
17775
17776         { &hf_smb_resume_find_id,
17777                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17778                 NULL, 0, "Handle for Find operation", HFILL }},
17779
17780         { &hf_smb_resume_server_cookie,
17781                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_NONE,
17782                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17783
17784         { &hf_smb_resume_client_cookie,
17785                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_NONE,
17786                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17787
17788         { &hf_smb_andxoffset,
17789                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17790                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17791
17792         { &hf_smb_lock_type_large,
17793                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17794                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17795
17796         { &hf_smb_lock_type_cancel,
17797                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17798                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17799
17800         { &hf_smb_lock_type_change,
17801                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17802                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17803
17804         { &hf_smb_lock_type_oplock,
17805                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17806                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17807
17808         { &hf_smb_lock_type_shared,
17809                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17810                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17811
17812         { &hf_smb_locking_ol,
17813                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17814                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17815
17816         { &hf_smb_number_of_locks,
17817                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17818                 NULL, 0, "Number of lock requests in this request", HFILL }},
17819
17820         { &hf_smb_number_of_unlocks,
17821                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17822                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17823
17824         { &hf_smb_lock_long_length,
17825                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17826                 NULL, 0, "Length of lock/unlock region", HFILL }},
17827
17828         { &hf_smb_lock_long_offset,
17829                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17830                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17831
17832         { &hf_smb_file_type,
17833                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17834                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17835
17836         { &hf_smb_ipc_state_nonblocking,
17837                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17838                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17839
17840         { &hf_smb_ipc_state_endpoint,
17841                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17842                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17843
17844         { &hf_smb_ipc_state_pipe_type,
17845                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17846                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17847
17848         { &hf_smb_ipc_state_read_mode,
17849                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17850                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17851
17852         { &hf_smb_ipc_state_icount,
17853                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17854                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17855
17856         { &hf_smb_server_fid,
17857                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17858                 NULL, 0, "Server unique File ID", HFILL }},
17859
17860         { &hf_smb_open_flags_add_info,
17861                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17862                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17863
17864         { &hf_smb_open_flags_ex_oplock,
17865                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17866                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17867
17868         { &hf_smb_open_flags_batch_oplock,
17869                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17870                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17871
17872         { &hf_smb_open_flags_ealen,
17873                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17874                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17875
17876         { &hf_smb_open_action_open,
17877                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17878                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17879
17880         { &hf_smb_open_action_lock,
17881                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17882                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17883
17884         { &hf_smb_vc_num,
17885                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17886                 NULL, 0, NULL, HFILL }},
17887
17888         { &hf_smb_password_len,
17889                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17890                 NULL, 0, "Length of password", HFILL }},
17891
17892         { &hf_smb_ansi_password_len,
17893                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17894                 NULL, 0, "Length of ANSI password", HFILL }},
17895
17896         { &hf_smb_unicode_password_len,
17897                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17898                 NULL, 0, "Length of Unicode password", HFILL }},
17899
17900         { &hf_smb_account,
17901                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17902                 NULL, 0, "Account, username", HFILL }},
17903
17904         { &hf_smb_os,
17905                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17906                 NULL, 0, "Which OS we are running", HFILL }},
17907
17908         { &hf_smb_lanman,
17909                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17910                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17911
17912         { &hf_smb_setup_action_guest,
17913                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17914                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17915
17916         { &hf_smb_fs,
17917                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17918                 NULL, 0, NULL, HFILL }},
17919
17920         { &hf_smb_connect_flags_dtid,
17921                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17922                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17923
17924         { &hf_smb_connect_support_search,
17925                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17926                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17927
17928         { &hf_smb_connect_support_in_dfs,
17929                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17930                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17931
17932         { &hf_smb_max_setup_count,
17933                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17934                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17935
17936         { &hf_smb_total_param_count,
17937                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17938                 NULL, 0, "Total number of parameter bytes", HFILL }},
17939
17940         { &hf_smb_total_data_count,
17941                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17942                 NULL, 0, "Total number of data bytes", HFILL }},
17943
17944         { &hf_smb_max_param_count,
17945                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17946                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17947
17948         { &hf_smb_max_data_count,
17949                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17950                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17951
17952         { &hf_smb_param_disp16,
17953                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17954                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17955
17956         { &hf_smb_param_count16,
17957                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17958                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17959
17960         { &hf_smb_param_offset16,
17961                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17962                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17963
17964         { &hf_smb_param_disp32,
17965                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17966                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17967
17968         { &hf_smb_param_count32,
17969                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17970                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17971
17972         { &hf_smb_param_offset32,
17973                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17974                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17975
17976         { &hf_smb_data_count16,
17977                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17978                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17979
17980         { &hf_smb_data_disp16,
17981                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17982                 NULL, 0, NULL, HFILL }},
17983
17984         { &hf_smb_data_offset16,
17985                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17986                 NULL, 0, NULL, HFILL }},
17987
17988         { &hf_smb_data_count32,
17989                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17990                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17991
17992         { &hf_smb_data_disp32,
17993                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17994                 NULL, 0, NULL, HFILL }},
17995
17996         { &hf_smb_data_offset32,
17997                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17998                 NULL, 0, NULL, HFILL }},
17999
18000         { &hf_smb_setup_count,
18001                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
18002                 NULL, 0, "Number of setup words in this buffer", HFILL }},
18003
18004         { &hf_smb_nt_ioctl_isfsctl,
18005                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
18006                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
18007
18008         { &hf_smb_nt_ioctl_flags_root_handle,
18009                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
18010                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
18011
18012         { &hf_smb_nt_notify_action,
18013                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
18014                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
18015
18016         { &hf_smb_nt_notify_watch_tree,
18017                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
18018                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
18019
18020         { &hf_smb_nt_notify_stream_write,
18021                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
18022                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
18023
18024         { &hf_smb_nt_notify_stream_size,
18025                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
18026                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
18027
18028         { &hf_smb_nt_notify_stream_name,
18029                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
18030                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
18031
18032         { &hf_smb_nt_notify_security,
18033                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
18034                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
18035
18036         { &hf_smb_nt_notify_ea,
18037                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
18038                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
18039
18040         { &hf_smb_nt_notify_creation,
18041                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
18042                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
18043
18044         { &hf_smb_nt_notify_last_access,
18045                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
18046                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
18047
18048         { &hf_smb_nt_notify_last_write,
18049                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
18050                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
18051
18052         { &hf_smb_nt_notify_size,
18053                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
18054                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
18055
18056         { &hf_smb_nt_notify_attributes,
18057                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
18058                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
18059
18060         { &hf_smb_nt_notify_dir_name,
18061                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
18062                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
18063
18064         { &hf_smb_nt_notify_file_name,
18065                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
18066                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
18067
18068         { &hf_smb_root_dir_fid,
18069                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
18070                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
18071
18072         { &hf_smb_alloc_size64,
18073                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
18074                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
18075
18076         { &hf_smb_nt_create_disposition,
18077                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
18078                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
18079
18080         { &hf_smb_sd_length,
18081                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
18082                 NULL, 0, "Total length of security descriptor", HFILL }},
18083
18084         { &hf_smb_ea_list_length,
18085                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
18086                 NULL, 0, "Total length of extended attributes", HFILL }},
18087
18088         { &hf_smb_ea_flags,
18089                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
18090                 NULL, 0, NULL, HFILL }},
18091
18092         { &hf_smb_ea_name_length,
18093                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
18094                 NULL, 0, NULL, HFILL }},
18095
18096         { &hf_smb_ea_data_length,
18097                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
18098                 NULL, 0, NULL, HFILL }},
18099
18100         { &hf_smb_ea_name,
18101                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
18102                 NULL, 0, NULL, HFILL }},
18103
18104         { &hf_smb_ea_data,
18105                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
18106                 NULL, 0, NULL, HFILL }},
18107
18108         { &hf_smb_file_name_len,
18109                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
18110                 NULL, 0, "Length of File Name", HFILL }},
18111
18112         { &hf_smb_nt_impersonation_level,
18113                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
18114                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
18115
18116         { &hf_smb_nt_security_flags_context_tracking,
18117                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
18118                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
18119
18120         { &hf_smb_nt_security_flags_effective_only,
18121                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
18122                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
18123
18124         { &hf_smb_nt_access_mask_generic_read,
18125                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
18126                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
18127
18128         { &hf_smb_nt_access_mask_generic_write,
18129                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
18130                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
18131
18132         { &hf_smb_nt_access_mask_generic_execute,
18133                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
18134                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
18135
18136         { &hf_smb_nt_access_mask_generic_all,
18137                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
18138                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
18139
18140         { &hf_smb_nt_access_mask_maximum_allowed,
18141                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
18142                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18143
18144         { &hf_smb_nt_access_mask_system_security,
18145                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18146                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18147
18148         { &hf_smb_nt_access_mask_synchronize,
18149                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18150                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18151
18152         { &hf_smb_nt_access_mask_write_owner,
18153                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18154                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18155
18156         { &hf_smb_nt_access_mask_write_dac,
18157                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18158                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18159
18160         { &hf_smb_nt_access_mask_read_control,
18161                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18162                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18163
18164         { &hf_smb_nt_access_mask_delete,
18165                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18166                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18167
18168         { &hf_smb_nt_access_mask_write_attributes,
18169                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18170                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18171
18172         { &hf_smb_nt_access_mask_read_attributes,
18173                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18174                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18175
18176         { &hf_smb_nt_access_mask_delete_child,
18177                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18178                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18179
18180         /*
18181          * "Execute" for files, "traverse" for directories.
18182          */
18183         { &hf_smb_nt_access_mask_execute,
18184                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18185                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18186
18187         { &hf_smb_nt_access_mask_write_ea,
18188                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18189                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18190
18191         { &hf_smb_nt_access_mask_read_ea,
18192                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18193                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18194
18195         /*
18196          * "Append data" for files, "add subdirectory" for directories,
18197          * "create pipe instance" for named pipes.
18198          */
18199         { &hf_smb_nt_access_mask_append,
18200                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18201                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18202
18203         /*
18204          * "Write data" for files and pipes, "add file" for directory.
18205          */
18206         { &hf_smb_nt_access_mask_write,
18207                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18208                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18209
18210         /*
18211          * "Read data" for files and pipes, "list directory" for directory.
18212          */
18213         { &hf_smb_nt_access_mask_read,
18214                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18215                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18216
18217         { &hf_smb_nt_create_bits_oplock,
18218                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18219                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18220
18221         { &hf_smb_nt_create_bits_boplock,
18222                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18223                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18224
18225         { &hf_smb_nt_create_bits_dir,
18226                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18227                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18228
18229         { &hf_smb_nt_create_bits_ext_resp,
18230           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
18231             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18232
18233         { &hf_smb_nt_create_options_directory_file,
18234                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18235                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18236
18237         { &hf_smb_nt_create_options_write_through,
18238                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18239                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18240
18241         { &hf_smb_nt_create_options_sequential_only,
18242                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18243                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to thsis file only be sequential?", HFILL }},
18244
18245         { &hf_smb_nt_create_options_no_intermediate_buffering,
18246                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
18247                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
18248
18249         { &hf_smb_nt_create_options_sync_io_alert,
18250                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18251                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18252
18253         { &hf_smb_nt_create_options_sync_io_nonalert,
18254                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18255                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18256
18257         { &hf_smb_nt_create_options_non_directory_file,
18258                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18259                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18260
18261         { &hf_smb_nt_create_options_create_tree_connection,
18262                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
18263                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
18264
18265         { &hf_smb_nt_create_options_complete_if_oplocked,
18266                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
18267                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
18268
18269         { &hf_smb_nt_create_options_no_ea_knowledge,
18270                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18271                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18272
18273         { &hf_smb_nt_create_options_eight_dot_three_only,
18274                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18275                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18276
18277         { &hf_smb_nt_create_options_random_access,
18278                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18279                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18280
18281         { &hf_smb_nt_create_options_delete_on_close,
18282                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18283                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18284         { &hf_smb_nt_create_options_open_by_fileid,
18285                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
18286                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
18287
18288         { &hf_smb_nt_create_options_backup_intent,
18289                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
18290                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
18291
18292         { &hf_smb_nt_create_options_no_compression,
18293                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
18294                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
18295
18296         { &hf_smb_nt_create_options_reserve_opfilter,
18297                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
18298                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
18299
18300         { &hf_smb_nt_create_options_open_reparse_point,
18301                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
18302                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
18303
18304         { &hf_smb_nt_create_options_open_no_recall,
18305                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
18306                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
18307
18308         { &hf_smb_nt_create_options_open_for_free_space_query,
18309                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
18310                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
18311
18312         { &hf_smb_nt_share_access_read,
18313                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18314                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
18315
18316         { &hf_smb_nt_share_access_write,
18317                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18318                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
18319
18320         { &hf_smb_nt_share_access_delete,
18321                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18322                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, NULL, HFILL }},
18323
18324         { &hf_smb_file_eattr_read_only,
18325                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18326                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18327
18328         { &hf_smb_file_eattr_hidden,
18329                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18330                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18331
18332         { &hf_smb_file_eattr_system,
18333                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18334                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18335
18336         { &hf_smb_file_eattr_volume,
18337                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18338                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18339
18340         { &hf_smb_file_eattr_directory,
18341                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18342                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18343
18344         { &hf_smb_file_eattr_archive,
18345                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18346                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18347
18348         { &hf_smb_file_eattr_device,
18349                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18350                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18351
18352         { &hf_smb_file_eattr_normal,
18353                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18354                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18355
18356         { &hf_smb_file_eattr_temporary,
18357                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18358                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18359
18360         { &hf_smb_file_eattr_sparse,
18361                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18362                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18363
18364         { &hf_smb_file_eattr_reparse,
18365                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18366                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18367
18368         { &hf_smb_file_eattr_compressed,
18369                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18370                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18371
18372         { &hf_smb_file_eattr_offline,
18373                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18374                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18375
18376         { &hf_smb_file_eattr_not_content_indexed,
18377                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18378                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18379
18380         { &hf_smb_file_eattr_encrypted,
18381                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18382                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18383
18384         { &hf_smb_sec_desc_len,
18385                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18386                 NULL, 0, "Security Descriptor Length", HFILL }},
18387
18388         { &hf_smb_nt_qsd_owner,
18389                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18390                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18391
18392         { &hf_smb_nt_qsd_group,
18393                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18394                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18395
18396         { &hf_smb_nt_qsd_dacl,
18397                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18398                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18399
18400         { &hf_smb_nt_qsd_sacl,
18401                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18402                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18403
18404         { &hf_smb_extended_attributes,
18405                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_NONE,
18406                 NULL, 0, NULL, HFILL }},
18407
18408         { &hf_smb_oplock_level,
18409                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18410                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18411
18412         { &hf_smb_create_action,
18413                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18414                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18415
18416         { &hf_smb_file_id,
18417                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18418                 NULL, 0, NULL, HFILL }},
18419
18420         { &hf_smb_ea_error_offset,
18421                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18422                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18423
18424         { &hf_smb_end_of_file,
18425                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18426                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18427
18428         { &hf_smb_replace,
18429                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18430                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18431
18432         { &hf_smb_root_dir_handle,
18433                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18434                 NULL, 0, "Root directory handle", HFILL }},
18435
18436         { &hf_smb_target_name_len,
18437                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18438                 NULL, 0, "Length of target file name", HFILL }},
18439
18440         { &hf_smb_target_name,
18441                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18442                 NULL, 0, "Target file name", HFILL }},
18443
18444         { &hf_smb_device_type,
18445                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18446                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18447
18448         { &hf_smb_is_directory,
18449                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18450                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18451
18452         { &hf_smb_next_entry_offset,
18453                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18454                 NULL, 0, "Offset to next entry", HFILL }},
18455
18456         { &hf_smb_change_time,
18457                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18458                 NULL, 0, "Last Change Time", HFILL }},
18459
18460         { &hf_smb_setup_len,
18461                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18462                 NULL, 0, "Length of printer setup data", HFILL }},
18463
18464         { &hf_smb_print_mode,
18465                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18466                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18467
18468         { &hf_smb_print_identifier,
18469                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18470                 NULL, 0, "Identifier string for this print job", HFILL }},
18471
18472         { &hf_smb_restart_index,
18473                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18474                 NULL, 0, "Index of entry after last returned", HFILL }},
18475
18476         { &hf_smb_print_queue_date,
18477                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18478                 NULL, 0, "Date when this entry was queued", HFILL }},
18479
18480         { &hf_smb_print_queue_dos_date,
18481                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18482                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18483
18484         { &hf_smb_print_queue_dos_time,
18485                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18486                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18487
18488         { &hf_smb_print_status,
18489                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18490                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18491
18492         { &hf_smb_print_spool_file_number,
18493                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18494                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18495
18496         { &hf_smb_print_spool_file_size,
18497                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18498                 NULL, 0, "Number of bytes in spool file", HFILL }},
18499
18500         { &hf_smb_print_spool_file_name,
18501                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
18502                 NULL, 0, "Name of client that submitted this job", HFILL }},
18503
18504         { &hf_smb_start_index,
18505                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18506                 NULL, 0, "First queue entry to return", HFILL }},
18507
18508         { &hf_smb_originator_name,
18509                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18510                 NULL, 0, "Name of sender of message", HFILL }},
18511
18512         { &hf_smb_destination_name,
18513                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18514                 NULL, 0, "Name of recipient of message", HFILL }},
18515
18516         { &hf_smb_message_len,
18517                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18518                 NULL, 0, "Length of message", HFILL }},
18519
18520         { &hf_smb_message,
18521                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18522                 NULL, 0, "Message text", HFILL }},
18523
18524         { &hf_smb_mgid,
18525                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18526                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18527
18528         { &hf_smb_forwarded_name,
18529                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18530                 NULL, 0, "Recipient name being forwarded", HFILL }},
18531
18532         { &hf_smb_machine_name,
18533                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18534                 NULL, 0, "Name of target machine", HFILL }},
18535
18536         { &hf_smb_cancel_to,
18537                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18538                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18539
18540         { &hf_smb_trans_name,
18541                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18542                 NULL, 0, "Name of transaction", HFILL }},
18543
18544         { &hf_smb_transaction_flags_dtid,
18545                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18546                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18547
18548         { &hf_smb_transaction_flags_owt,
18549                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18550                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18551
18552         { &hf_smb_search_count,
18553                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18554                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18555
18556         { &hf_smb_search_pattern,
18557                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18558                 NULL, 0, NULL, HFILL }},
18559
18560         { &hf_smb_ff2_backup,
18561                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18562                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18563
18564         { &hf_smb_ff2_continue,
18565                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18566                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18567
18568         { &hf_smb_ff2_resume,
18569                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18570                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18571
18572         { &hf_smb_ff2_close_eos,
18573                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18574                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18575
18576         { &hf_smb_ff2_close,
18577                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18578                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18579
18580         { &hf_smb_ff2_information_level,
18581                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18582                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18583
18584         { &hf_smb_qpi_loi,
18585                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18586                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18587
18588         { &hf_smb_spi_loi,
18589                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18590                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18591
18592 #if 0
18593         { &hf_smb_sfi_writetru,
18594                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18595                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18596
18597         { &hf_smb_sfi_caching,
18598                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18599                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18600 #endif
18601
18602         { &hf_smb_storage_type,
18603                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18604                 NULL, 0, "Type of storage", HFILL }},
18605
18606         { &hf_smb_resume,
18607                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18608                 NULL, 0, NULL, HFILL }},
18609
18610         { &hf_smb_max_referral_level,
18611                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18612                 NULL, 0, "Latest referral version number understood", HFILL }},
18613
18614         { &hf_smb_qfsi_information_level,
18615                 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
18616                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18617
18618         { &hf_smb_nt_rename_level,
18619                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18620                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18621
18622         { &hf_smb_cluster_count,
18623                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18624                 NULL, 0, "Number of clusters", HFILL }},
18625
18626         { &hf_smb_number_of_links,
18627                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18628                 NULL, 0, "Number of hard links to the file", HFILL }},
18629
18630         { &hf_smb_delete_pending,
18631                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18632                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18633
18634         { &hf_smb_index_number,
18635                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
18636                 NULL, 0, "File system unique identifier", HFILL }},
18637
18638         { &hf_smb_position,
18639                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
18640                 NULL, 0, "File position", HFILL }},
18641
18642         { &hf_smb_current_offset,
18643                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18644                 NULL, 0, "Current offset in the file", HFILL }},
18645
18646         { &hf_smb_t2_alignment,
18647                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18648                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18649
18650         { &hf_smb_t2_stream_name_length,
18651                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18652                 NULL, 0, "Length of stream name", HFILL }},
18653
18654         { &hf_smb_t2_stream_size,
18655                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18656                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18657
18658         { &hf_smb_t2_stream_name,
18659                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18660                 NULL, 0, "Name of the stream", HFILL }},
18661
18662         { &hf_smb_t2_compressed_file_size,
18663                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18664                 NULL, 0, "Size of the compressed file", HFILL }},
18665
18666         { &hf_smb_t2_compressed_format,
18667                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18668                 NULL, 0, "Compression algorithm used", HFILL }},
18669
18670         { &hf_smb_t2_compressed_unit_shift,
18671                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18672                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18673
18674         { &hf_smb_t2_compressed_chunk_shift,
18675                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18676                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18677
18678         { &hf_smb_t2_compressed_cluster_shift,
18679                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18680                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18681
18682         { &hf_smb_t2_marked_for_deletion,
18683                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18684                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18685
18686         { &hf_smb_dfs_path_consumed,
18687                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18688                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18689
18690         { &hf_smb_dfs_num_referrals,
18691                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18692                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18693
18694         { &hf_smb_get_dfs_server_hold_storage,
18695                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18696                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18697
18698         { &hf_smb_get_dfs_fielding,
18699                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18700                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18701
18702         { &hf_smb_dfs_referral_version,
18703                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18704                 NULL, 0, "Version of referral element", HFILL }},
18705
18706         { &hf_smb_dfs_referral_size,
18707                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18708                 NULL, 0, "Size of referral element", HFILL }},
18709
18710         { &hf_smb_dfs_referral_server_type,
18711                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18712                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18713
18714         { &hf_smb_dfs_referral_flags_name_list_referral,
18715                 { "NameListReferral", "smb.dfs.referral.flags.name_list_referral", FT_BOOLEAN, 16,
18716                 TFS(&tfs_dfs_referral_flags_name_list_referral), REFENT_FLAGS_NAME_LIST_REFERRAL, "Is a domain/DC referral response?", HFILL }},
18717
18718         { &hf_smb_dfs_referral_flags_target_set_boundary,
18719                 { "TargetSetBoundary", "smb.dfs.referral.flags.target_set_boundary", FT_BOOLEAN, 16,
18720                 TFS(&tfs_dfs_referral_flags_target_set_boundary), REFENT_FLAGS_TARGET_SET_BOUNDARY, "Is this a first target in the target set?", HFILL }},
18721
18722         { &hf_smb_dfs_referral_node_offset,
18723                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18724                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18725
18726         { &hf_smb_dfs_referral_node,
18727                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18728                 NULL, 0, "Name of entity to visit next", HFILL }},
18729
18730         { &hf_smb_dfs_referral_proximity,
18731                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT32, BASE_DEC,
18732                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18733
18734         { &hf_smb_dfs_referral_ttl,
18735                 { "TTL", "smb.dfs.referral.ttl", FT_UINT32, BASE_DEC,
18736                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18737
18738         { &hf_smb_dfs_referral_path_offset,
18739                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18740                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18741
18742         { &hf_smb_dfs_referral_path,
18743                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18744                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18745
18746         { &hf_smb_dfs_referral_alt_path_offset,
18747                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18748                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18749
18750         { &hf_smb_dfs_referral_alt_path,
18751                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18752                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18753
18754         { &hf_smb_dfs_referral_domain_offset,
18755                 { "Domain Offset", "smb.dfs.referral.domain_offset", FT_UINT16, BASE_DEC,
18756                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18757
18758         { &hf_smb_dfs_referral_number_of_expnames,
18759                 { "Number of Expanded Names", "smb.dfs.referral.number_of_expnames", FT_UINT16, BASE_DEC,
18760                 NULL, 0, "Number of expanded names", HFILL }},
18761
18762         { &hf_smb_dfs_referral_expnames_offset,
18763                 { "Expanded Names Offset", "smb.dfs.referral.expnames_offset", FT_UINT16, BASE_DEC,
18764                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18765
18766         { &hf_smb_dfs_referral_domain_name,
18767                 { "Domain Name", "smb.dfs.referral.domain_name", FT_STRING, BASE_NONE,
18768                 NULL, 0, "Dfs referral domain name", HFILL }},
18769
18770         { &hf_smb_dfs_referral_expname,
18771                 { "Expanded Name", "smb.dfs.referral.expname", FT_STRING, BASE_NONE,
18772                 NULL, 0, "Dfs expanded name", HFILL }},
18773
18774         { &hf_smb_dfs_referral_server_guid,
18775                 { "Server GUID", "smb.dfs.referral.server_guid", FT_BYTES, BASE_HEX,
18776                 NULL, 0, "Globally unique identifier for this server", HFILL }},
18777
18778         { &hf_smb_end_of_search,
18779                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18780                 NULL, 0, "Was last entry returned?", HFILL }},
18781
18782         { &hf_smb_last_name_offset,
18783                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18784                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18785
18786         { &hf_smb_fn_information_level,
18787                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18788                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18789
18790         { &hf_smb_monitor_handle,
18791                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18792                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18793
18794         { &hf_smb_change_count,
18795                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18796                 NULL, 0, "Number of changes to wait for", HFILL }},
18797
18798         { &hf_smb_file_index,
18799                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18800                 NULL, 0, "File index", HFILL }},
18801
18802         { &hf_smb_short_file_name,
18803                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18804                 NULL, 0, "Short (8.3) File Name", HFILL }},
18805
18806         { &hf_smb_short_file_name_len,
18807                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18808                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18809
18810         { &hf_smb_fs_id,
18811                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18812                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18813
18814         { &hf_smb_sector_unit,
18815                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18816                 NULL, 0, "Sectors per allocation unit", HFILL }},
18817
18818         { &hf_smb_fs_units,
18819                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18820                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18821
18822         { &hf_smb_fs_sector,
18823                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18824                 NULL, 0, "Bytes per sector", HFILL }},
18825
18826         { &hf_smb_avail_units,
18827                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18828                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18829
18830         { &hf_smb_volume_serial_num,
18831                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18832                 NULL, 0, "Volume serial number", HFILL }},
18833
18834         { &hf_smb_volume_label_len,
18835                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18836                 NULL, 0, "Length of volume label", HFILL }},
18837
18838         { &hf_smb_volume_label,
18839                 { "Label", "smb.volume.label", FT_STRING, BASE_NONE,
18840                 NULL, 0, "Volume label", HFILL }},
18841
18842         { &hf_smb_free_alloc_units64,
18843                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18844                 NULL, 0, "Number of free allocation units", HFILL }},
18845
18846         { &hf_smb_caller_free_alloc_units64,
18847                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18848                 NULL, 0, "Number of caller free allocation units", HFILL }},
18849
18850         { &hf_smb_actual_free_alloc_units64,
18851                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18852                 NULL, 0, "Number of actual free allocation units", HFILL }},
18853
18854         { &hf_smb_soft_quota_limit,
18855                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18856                 NULL, 0, "Soft Quota treshold", HFILL }},
18857
18858         { &hf_smb_hard_quota_limit,
18859                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18860                 NULL, 0, "Hard Quota limit", HFILL }},
18861
18862         { &hf_smb_user_quota_used,
18863                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18864                 NULL, 0, "How much Quota is used by this user", HFILL }},
18865
18866         { &hf_smb_max_name_len,
18867                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18868                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18869
18870         { &hf_smb_fs_name_len,
18871                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18872                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18873
18874         { &hf_smb_fs_name,
18875                 { "FS Name", "smb.fs_name", FT_STRING, BASE_NONE,
18876                 NULL, 0, "Name of filesystem", HFILL }},
18877
18878         { &hf_smb_device_char_removable,
18879                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18880                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18881
18882         { &hf_smb_device_char_read_only,
18883                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18884                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18885
18886         { &hf_smb_device_char_floppy,
18887                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18888                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18889
18890         { &hf_smb_device_char_write_once,
18891                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18892                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18893
18894         { &hf_smb_device_char_remote,
18895                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18896                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18897
18898         { &hf_smb_device_char_mounted,
18899                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18900                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18901
18902         { &hf_smb_device_char_virtual,
18903                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18904                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18905
18906         { &hf_smb_fs_attr_css,
18907                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18908                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18909
18910         { &hf_smb_fs_attr_cpn,
18911                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18912                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18913
18914         { &hf_smb_fs_attr_uod,
18915                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
18916                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
18917
18918         { &hf_smb_fs_attr_pacls,
18919                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18920                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
18921
18922         { &hf_smb_fs_attr_fc,
18923                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18924                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
18925
18926         { &hf_smb_fs_attr_vq,
18927                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18928                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
18929
18930         { &hf_smb_fs_attr_ssf,
18931                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
18932                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
18933
18934         { &hf_smb_fs_attr_srp,
18935                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
18936                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
18937
18938         { &hf_smb_fs_attr_srs,
18939                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
18940                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
18941
18942         { &hf_smb_fs_attr_sla,
18943                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
18944                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
18945
18946         { &hf_smb_fs_attr_vic,
18947                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
18948                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
18949
18950         { &hf_smb_fs_attr_soids,
18951                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
18952                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
18953
18954         { &hf_smb_fs_attr_se,
18955                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
18956                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
18957
18958         { &hf_smb_fs_attr_ns,
18959                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
18960                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
18961
18962         { &hf_smb_fs_attr_rov,
18963                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
18964                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
18965
18966         { &hf_smb_user_quota_offset,
18967                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18968                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18969
18970         { &hf_smb_pipe_write_len,
18971                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18972                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18973
18974         { &hf_smb_quota_flags_deny_disk,
18975                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18976                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18977
18978         { &hf_smb_quota_flags_log_limit,
18979                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18980                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18981
18982         { &hf_smb_quota_flags_log_warning,
18983                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18984                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18985
18986         { &hf_smb_quota_flags_enabled,
18987                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18988                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18989
18990         { &hf_smb_segment_overlap,
18991                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18992                         "Fragment overlaps with other fragments", HFILL }},
18993
18994         { &hf_smb_segment_overlap_conflict,
18995                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18996                         "Overlapping fragments contained conflicting data", HFILL }},
18997
18998         { &hf_smb_segment_multiple_tails,
18999                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19000                         "Several tails were found when defragmenting the packet", HFILL }},
19001
19002         { &hf_smb_segment_too_long_fragment,
19003                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19004                         "Fragment contained data past end of packet", HFILL }},
19005
19006         { &hf_smb_segment_error,
19007                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19008                         "Defragmentation error due to illegal fragments", HFILL }},
19009
19010         { &hf_smb_opened_in,
19011                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19012                         "The frame this fid was opened", HFILL }},
19013
19014         { &hf_smb_closed_in,
19015                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19016                         "The frame this fid was closed", HFILL }},
19017
19018         { &hf_smb_mapped_in,
19019                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19020                         "The frame this share was mapped", HFILL }},
19021
19022         { &hf_smb_unmapped_in,
19023                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19024                         "The frame this share was unmapped", HFILL }},
19025
19026         { &hf_smb_segment,
19027                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19028                         NULL, HFILL }},
19029
19030         { &hf_smb_segments,
19031                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
19032                         NULL, HFILL }},
19033
19034         { &hf_smb_unix_major_version,
19035           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
19036             NULL, 0, "UNIX Major Version", HFILL }},
19037
19038         { &hf_smb_unix_minor_version,
19039           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
19040             NULL, 0, "UNIX Minor Version", HFILL }},
19041
19042         { &hf_smb_unix_capability_fcntl,
19043           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
19044                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
19045
19046         { &hf_smb_unix_capability_posix_acl,
19047           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
19048                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
19049
19050         { &hf_smb_file_access_mask_read_data,
19051           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
19052                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
19053
19054         { &hf_smb_file_access_mask_write_data,
19055           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
19056                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
19057
19058         { &hf_smb_file_access_mask_append_data,
19059           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
19060                 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
19061
19062         { &hf_smb_file_access_mask_read_ea,
19063           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
19064                 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
19065
19066         { &hf_smb_file_access_mask_write_ea,
19067           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
19068                 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
19069
19070         { &hf_smb_file_access_mask_execute,
19071           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
19072                 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
19073
19074         { &hf_smb_file_access_mask_read_attribute,
19075           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
19076                 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
19077
19078         { &hf_smb_file_access_mask_write_attribute,
19079           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
19080                 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
19081
19082         { &hf_smb_dir_access_mask_list,
19083           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
19084                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
19085
19086         { &hf_smb_dir_access_mask_add_file,
19087           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
19088                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
19089
19090         { &hf_smb_dir_access_mask_add_subdir,
19091           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
19092                 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
19093
19094         { &hf_smb_dir_access_mask_read_ea,
19095           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
19096                 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
19097
19098         { &hf_smb_dir_access_mask_write_ea,
19099           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
19100                 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
19101
19102         { &hf_smb_dir_access_mask_traverse,
19103           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
19104                 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
19105
19106         { &hf_smb_dir_access_mask_delete_child,
19107           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
19108                 TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
19109
19110         { &hf_smb_dir_access_mask_read_attribute,
19111           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
19112                 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
19113
19114         { &hf_smb_dir_access_mask_write_attribute,
19115           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
19116                 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
19117
19118         { &hf_smb_unix_file_size,
19119           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
19120             NULL, 0, NULL, HFILL }},
19121
19122         { &hf_smb_unix_file_num_bytes,
19123           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
19124             NULL, 0, "Number of bytes used to store the file", HFILL }},
19125
19126         { &hf_smb_unix_file_last_status,
19127           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
19128             NULL, 0, NULL, HFILL }},
19129
19130         { &hf_smb_unix_file_last_access,
19131           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
19132             NULL, 0, NULL, HFILL }},
19133
19134         { &hf_smb_unix_file_last_change,
19135           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
19136             NULL, 0, NULL, HFILL }},
19137
19138         { &hf_smb_unix_file_uid,
19139           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
19140             NULL, 0, NULL, HFILL }},
19141
19142         { &hf_smb_unix_file_gid,
19143           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
19144             NULL, 0, NULL, HFILL }},
19145
19146         { &hf_smb_unix_file_type,
19147           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
19148             VALS(unix_file_type_vals), 0, NULL, HFILL }},
19149
19150         { &hf_smb_unix_file_dev_major,
19151           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
19152             NULL, 0, NULL, HFILL }},
19153
19154         { &hf_smb_unix_file_dev_minor,
19155           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
19156             NULL, 0, NULL, HFILL }},
19157
19158         { &hf_smb_unix_file_unique_id,
19159           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
19160             NULL, 0, NULL, HFILL }},
19161
19162         { &hf_smb_unix_file_permissions,
19163           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
19164             NULL, 0, NULL, HFILL }},
19165
19166         { &hf_smb_unix_file_nlinks,
19167           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
19168             NULL, 0, NULL, HFILL }},
19169
19170         { &hf_smb_unix_file_link_dest,
19171           { "Link destination", "smb.unix.file.link_dest", FT_STRING,
19172             BASE_NONE, NULL, 0, NULL, HFILL }},
19173
19174         { &hf_smb_unix_find_file_nextoffset,
19175           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
19176             NULL, 0, NULL, HFILL }},
19177
19178         { &hf_smb_unix_find_file_resumekey,
19179           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
19180             NULL, 0, NULL, HFILL }},
19181
19182         { &hf_smb_network_unknown,
19183           { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
19184             NULL, 0, NULL, HFILL }},
19185
19186         { &hf_smb_create_flags,
19187           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
19188             NULL, 0, NULL, HFILL }},
19189
19190         { &hf_smb_create_options,
19191           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
19192             NULL, 0, NULL, HFILL }},
19193
19194         { &hf_smb_share_access,
19195           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
19196             NULL, 0, NULL, HFILL }},
19197
19198         { &hf_smb_access_mask,
19199           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
19200             NULL, 0, NULL, HFILL }},
19201
19202         { &hf_smb_mode,
19203           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
19204             NULL, 0, NULL, HFILL }},
19205
19206         { &hf_smb_attribute,
19207           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
19208             NULL, 0, NULL, HFILL }},
19209
19210         { &hf_smb_reparse_tag,
19211           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
19212             NULL, 0, NULL, HFILL }},
19213
19214         { &hf_smb_disposition_delete_on_close,
19215           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
19216                 TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
19217
19218         { &hf_smb_pipe_info_flag,
19219           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
19220                 TFS(&tfs_pipe_info_flag), 0x01, NULL, HFILL }},
19221
19222         { &hf_smb_logged_in,
19223           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_NONE,
19224                 NULL, 0, NULL, HFILL }},
19225
19226         { &hf_smb_logged_out,
19227           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_NONE,
19228                 NULL, 0, NULL, HFILL }},
19229
19230         { &hf_smb_file_rw_offset,
19231           { "File Offset", "smb.file.rw.offset", FT_UINT32, BASE_DEC,
19232                 NULL, 0, NULL, HFILL }},
19233
19234         { &hf_smb_file_rw_length,
19235           { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
19236                 NULL, 0, NULL, HFILL }},
19237
19238         { &hf_smb_posix_acl_version,
19239           { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
19240                 NULL, 0, NULL, HFILL }},
19241
19242         { &hf_smb_posix_num_file_aces,
19243           { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
19244                 NULL, 0, NULL, HFILL }},
19245
19246         { &hf_smb_posix_num_def_aces,
19247           { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
19248                 NULL, 0, NULL, HFILL }},
19249
19250         { &hf_smb_posix_ace_type,
19251           { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
19252                 VALS(&ace_type_vals), 0, NULL, HFILL }},
19253
19254         { &hf_smb_posix_ace_flags,
19255           { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
19256                 NULL, 0, NULL, HFILL }},
19257
19258         { &hf_smb_posix_ace_perm_read,
19259           {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
19260                 NULL, 0x04, NULL, HFILL}},
19261
19262         { &hf_smb_posix_ace_perm_write,
19263           {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
19264                 NULL, 0x02, NULL, HFILL}},
19265
19266         { &hf_smb_posix_ace_perm_execute,
19267           {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
19268                 NULL, 0x01, NULL, HFILL}},
19269
19270         { &hf_smb_posix_ace_perm_owner_uid,
19271           { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
19272                 NULL, 0, NULL, HFILL }},
19273
19274         { &hf_smb_posix_ace_perm_owner_gid,
19275           { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
19276                 NULL, 0, NULL, HFILL }},
19277
19278         { &hf_smb_posix_ace_perm_uid,
19279           { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
19280                 NULL, 0, NULL, HFILL }},
19281
19282         { &hf_smb_posix_ace_perm_gid,
19283           { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
19284                 NULL, 0, NULL, HFILL }},
19285
19286         };
19287
19288         static gint *ett[] = {
19289                 &ett_smb,
19290                 &ett_smb_fid,
19291                 &ett_smb_tid,
19292                 &ett_smb_uid,
19293                 &ett_smb_hdr,
19294                 &ett_smb_command,
19295                 &ett_smb_fileattributes,
19296                 &ett_smb_capabilities,
19297                 &ett_smb_aflags,
19298                 &ett_smb_dialect,
19299                 &ett_smb_dialects,
19300                 &ett_smb_mode,
19301                 &ett_smb_rawmode,
19302                 &ett_smb_flags,
19303                 &ett_smb_flags2,
19304                 &ett_smb_desiredaccess,
19305                 &ett_smb_search,
19306                 &ett_smb_file,
19307                 &ett_smb_openfunction,
19308                 &ett_smb_filetype,
19309                 &ett_smb_openaction,
19310                 &ett_smb_writemode,
19311                 &ett_smb_lock_type,
19312                 &ett_smb_ssetupandxaction,
19313                 &ett_smb_optionsup,
19314                 &ett_smb_time_date,
19315                 &ett_smb_move_copy_flags,
19316                 &ett_smb_file_attributes,
19317                 &ett_smb_search_resume_key,
19318                 &ett_smb_search_dir_info,
19319                 &ett_smb_unlocks,
19320                 &ett_smb_unlock,
19321                 &ett_smb_locks,
19322                 &ett_smb_lock,
19323                 &ett_smb_open_flags,
19324                 &ett_smb_ipc_state,
19325                 &ett_smb_open_action,
19326                 &ett_smb_setup_action,
19327                 &ett_smb_connect_flags,
19328                 &ett_smb_connect_support_bits,
19329                 &ett_smb_nt_access_mask,
19330                 &ett_smb_nt_create_bits,
19331                 &ett_smb_nt_create_options,
19332                 &ett_smb_nt_share_access,
19333                 &ett_smb_nt_security_flags,
19334                 &ett_smb_nt_trans_setup,
19335                 &ett_smb_nt_trans_data,
19336                 &ett_smb_nt_trans_param,
19337                 &ett_smb_nt_notify_completion_filter,
19338                 &ett_smb_nt_ioctl_flags,
19339                 &ett_smb_security_information_mask,
19340                 &ett_smb_print_queue_entry,
19341                 &ett_smb_transaction_flags,
19342                 &ett_smb_transaction_params,
19343                 &ett_smb_find_first2_flags,
19344 #if 0
19345                 &ett_smb_ioflag,
19346 #endif
19347                 &ett_smb_transaction_data,
19348                 &ett_smb_stream_info,
19349                 &ett_smb_dfs_referrals,
19350                 &ett_smb_dfs_referral,
19351                 &ett_smb_dfs_referral_flags,
19352                 &ett_smb_dfs_referral_expnames,
19353                 &ett_smb_get_dfs_flags,
19354                 &ett_smb_ff2_data,
19355                 &ett_smb_device_characteristics,
19356                 &ett_smb_fs_attributes,
19357                 &ett_smb_segments,
19358                 &ett_smb_segment,
19359                 &ett_smb_quotaflags,
19360                 &ett_smb_secblob,
19361                 &ett_smb_mac_support_flags,
19362                 &ett_smb_unicode_password,
19363                 &ett_smb_ea,
19364                 &ett_smb_unix_capabilities,
19365                 &ett_smb_posic_ace,
19366                 &ett_smb_posix_ace_perms
19367         };
19368         module_t *smb_module;
19369
19370         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19371             "SMB", "smb");
19372         proto_register_subtree_array(ett, array_length(ett));
19373         proto_register_field_array(proto_smb, hf, array_length(hf));
19374
19375         proto_do_register_windows_common(proto_smb);
19376
19377         register_init_routine(&smb_init_protocol);
19378         smb_module = prefs_register_protocol(proto_smb, NULL);
19379         prefs_register_bool_preference(smb_module, "trans_reassembly",
19380                 "Reassemble SMB Transaction payload",
19381                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19382                 &smb_trans_reassembly);
19383         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19384                 "Reassemble DCERPC over SMB",
19385                 "Whether the dissector should reassemble DCERPC over SMB commands",
19386                 &smb_dcerpc_reassembly);
19387         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19388                 "Snoop SID to Name mappings",
19389                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19390                 &sid_name_snooping);
19391
19392         register_init_routine(smb_trans_reassembly_init);
19393         smb_tap = register_tap("smb");
19394
19395         register_dissector("smb", dissect_smb, proto_smb);
19396 }
19397
19398 void
19399 proto_reg_handoff_smb(void)
19400 {
19401         dissector_handle_t smb_handle;
19402
19403         gssapi_handle = find_dissector("gssapi");
19404         ntlmssp_handle = find_dissector("ntlmssp");
19405
19406         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19407         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19408         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19409
19410         smb_handle = find_dissector("smb");
19411         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19412         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19413         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
19414         dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
19415 }