we need to track the fid in the rwdata structure so that reassembly of
[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 static int proto_smb = -1;
97 static int hf_smb_cmd = -1;
98 static int hf_smb_mapped_in = -1;
99 static int hf_smb_unmapped_in = -1;
100 static int hf_smb_opened_in = -1;
101 static int hf_smb_closed_in = -1;
102 static int hf_smb_key = -1;
103 static int hf_smb_session_id = -1;
104 static int hf_smb_sequence_num = -1;
105 static int hf_smb_group_id = -1;
106 static int hf_smb_pid = -1;
107 static int hf_smb_tid = -1;
108 static int hf_smb_uid = -1;
109 static int hf_smb_mid = -1;
110 static int hf_smb_pid_high = -1;
111 static int hf_smb_sig = -1;
112 static int hf_smb_response_to = -1;
113 static int hf_smb_time = -1;
114 static int hf_smb_response_in = -1;
115 static int hf_smb_continuation_to = -1;
116 static int hf_smb_nt_status = -1;
117 static int hf_smb_error_class = -1;
118 static int hf_smb_error_code = -1;
119 static int hf_smb_reserved = -1;
120 static int hf_smb_create_flags = -1;
121 static int hf_smb_create_options = -1;
122 static int hf_smb_share_access = -1;
123 static int hf_smb_access_mask = -1;
124 static int hf_smb_flags_lock = -1;
125 static int hf_smb_flags_receive_buffer = -1;
126 static int hf_smb_flags_caseless = -1;
127 static int hf_smb_flags_canon = -1;
128 static int hf_smb_flags_oplock = -1;
129 static int hf_smb_flags_notify = -1;
130 static int hf_smb_flags_response = -1;
131 static int hf_smb_flags2_long_names_allowed = -1;
132 static int hf_smb_flags2_ea = -1;
133 static int hf_smb_flags2_sec_sig = -1;
134 static int hf_smb_flags2_long_names_used = -1;
135 static int hf_smb_flags2_esn = -1;
136 static int hf_smb_flags2_dfs = -1;
137 static int hf_smb_flags2_roe = -1;
138 static int hf_smb_flags2_nt_error = -1;
139 static int hf_smb_flags2_string = -1;
140 static int hf_smb_word_count = -1;
141 static int hf_smb_byte_count = -1;
142 static int hf_smb_buffer_format = -1;
143 static int hf_smb_dialect_name = -1;
144 static int hf_smb_dialect_index = -1;
145 static int hf_smb_max_trans_buf_size = -1;
146 static int hf_smb_max_mpx_count = -1;
147 static int hf_smb_max_vcs_num = -1;
148 static int hf_smb_session_key = -1;
149 static int hf_smb_server_timezone = -1;
150 static int hf_smb_encryption_key_length = -1;
151 static int hf_smb_encryption_key = -1;
152 static int hf_smb_primary_domain = -1;
153 static int hf_smb_server = -1;
154 static int hf_smb_max_raw_buf_size = -1;
155 static int hf_smb_server_guid = -1;
156 static int hf_smb_security_blob_len = -1;
157 static int hf_smb_security_blob = -1;
158 static int hf_smb_sm_mode16 = -1;
159 static int hf_smb_sm_password16 = -1;
160 static int hf_smb_sm_mode = -1;
161 static int hf_smb_sm_password = -1;
162 static int hf_smb_sm_signatures = -1;
163 static int hf_smb_sm_sig_required = -1;
164 static int hf_smb_rm_read = -1;
165 static int hf_smb_rm_write = -1;
166 static int hf_smb_server_date_time = -1;
167 static int hf_smb_server_smb_date = -1;
168 static int hf_smb_server_smb_time = -1;
169 static int hf_smb_server_cap_raw_mode = -1;
170 static int hf_smb_server_cap_mpx_mode = -1;
171 static int hf_smb_server_cap_unicode = -1;
172 static int hf_smb_server_cap_large_files = -1;
173 static int hf_smb_server_cap_nt_smbs = -1;
174 static int hf_smb_server_cap_rpc_remote_apis = -1;
175 static int hf_smb_server_cap_nt_status = -1;
176 static int hf_smb_server_cap_level_ii_oplocks = -1;
177 static int hf_smb_server_cap_lock_and_read = -1;
178 static int hf_smb_server_cap_nt_find = -1;
179 static int hf_smb_server_cap_dfs = -1;
180 static int hf_smb_server_cap_infolevel_passthru = -1;
181 static int hf_smb_server_cap_large_readx = -1;
182 static int hf_smb_server_cap_large_writex = -1;
183 static int hf_smb_server_cap_unix = -1;
184 static int hf_smb_server_cap_reserved = -1;
185 static int hf_smb_server_cap_bulk_transfer = -1;
186 static int hf_smb_server_cap_compressed_data = -1;
187 static int hf_smb_server_cap_extended_security = -1;
188 static int hf_smb_system_time = -1;
189 static int hf_smb_unknown = -1;
190 static int hf_smb_dir_name = -1;
191 static int hf_smb_echo_count = -1;
192 static int hf_smb_echo_data = -1;
193 static int hf_smb_echo_seq_num = -1;
194 static int hf_smb_max_buf_size = -1;
195 static int hf_smb_password = -1;
196 static int hf_smb_password_len = -1;
197 static int hf_smb_ansi_password = -1;
198 static int hf_smb_ansi_password_len = -1;
199 static int hf_smb_unicode_password = -1;
200 static int hf_smb_unicode_password_len = -1;
201 static int hf_smb_path = -1;
202 static int hf_smb_service = -1;
203 static int hf_smb_move_flags_file = -1;
204 static int hf_smb_move_flags_dir = -1;
205 static int hf_smb_move_flags_verify = -1;
206 static int hf_smb_files_moved = -1;
207 static int hf_smb_file_access_mask_read_data = -1;
208 static int hf_smb_file_access_mask_write_data = -1;
209 static int hf_smb_file_access_mask_append_data = -1;
210 static int hf_smb_file_access_mask_read_ea = -1;
211 static int hf_smb_file_access_mask_write_ea = -1;
212 static int hf_smb_file_access_mask_execute = -1;
213 static int hf_smb_file_access_mask_read_attribute = -1;
214 static int hf_smb_file_access_mask_write_attribute = -1;
215 static int hf_smb_dir_access_mask_list = -1;
216 static int hf_smb_dir_access_mask_add_file = -1;
217 static int hf_smb_dir_access_mask_add_subdir = -1;
218 static int hf_smb_dir_access_mask_read_ea = -1;
219 static int hf_smb_dir_access_mask_write_ea = -1;
220 static int hf_smb_dir_access_mask_traverse = -1;
221 static int hf_smb_dir_access_mask_delete_child = -1;
222 static int hf_smb_dir_access_mask_read_attribute = -1;
223 static int hf_smb_dir_access_mask_write_attribute = -1;
224 static int hf_smb_copy_flags_file = -1;
225 static int hf_smb_copy_flags_dir = -1;
226 static int hf_smb_copy_flags_dest_mode = -1;
227 static int hf_smb_copy_flags_source_mode = -1;
228 static int hf_smb_copy_flags_verify = -1;
229 static int hf_smb_copy_flags_tree_copy = -1;
230 static int hf_smb_copy_flags_ea_action = -1;
231 static int hf_smb_count = -1;
232 static int hf_smb_count_low = -1;
233 static int hf_smb_count_high = -1;
234 static int hf_smb_file_name = -1;
235 static int hf_smb_open_function_open = -1;
236 static int hf_smb_open_function_create = -1;
237 static int hf_smb_fid = -1;
238 static int hf_smb_file_attr_read_only_16bit = -1;
239 static int hf_smb_file_attr_read_only_8bit = -1;
240 static int hf_smb_file_attr_hidden_16bit = -1;
241 static int hf_smb_file_attr_hidden_8bit = -1;
242 static int hf_smb_file_attr_system_16bit = -1;
243 static int hf_smb_file_attr_system_8bit = -1;
244 static int hf_smb_file_attr_volume_16bit = -1;
245 static int hf_smb_file_attr_volume_8bit = -1;
246 static int hf_smb_file_attr_directory_16bit = -1;
247 static int hf_smb_file_attr_directory_8bit = -1;
248 static int hf_smb_file_attr_archive_16bit = -1;
249 static int hf_smb_file_attr_archive_8bit = -1;
250 static int hf_smb_file_attr_device = -1;
251 static int hf_smb_file_attr_normal = -1;
252 static int hf_smb_file_attr_temporary = -1;
253 static int hf_smb_file_attr_sparse = -1;
254 static int hf_smb_file_attr_reparse = -1;
255 static int hf_smb_file_attr_compressed = -1;
256 static int hf_smb_file_attr_offline = -1;
257 static int hf_smb_file_attr_not_content_indexed = -1;
258 static int hf_smb_file_attr_encrypted = -1;
259 static int hf_smb_file_size = -1;
260 static int hf_smb_search_attribute_read_only = -1;
261 static int hf_smb_search_attribute_hidden = -1;
262 static int hf_smb_search_attribute_system = -1;
263 static int hf_smb_search_attribute_volume = -1;
264 static int hf_smb_search_attribute_directory = -1;
265 static int hf_smb_search_attribute_archive = -1;
266 static int hf_smb_access_mode = -1;
267 static int hf_smb_access_sharing = -1;
268 static int hf_smb_access_locality = -1;
269 static int hf_smb_access_caching = -1;
270 static int hf_smb_access_writetru = -1;
271 static int hf_smb_create_time = -1;
272 static int hf_smb_modify_time = -1;
273 static int hf_smb_backup_time = -1;
274 static int hf_smb_mac_alloc_block_count = -1;
275 static int hf_smb_mac_alloc_block_size = -1;
276 static int hf_smb_mac_free_block_count = -1;
277 static int hf_smb_mac_fndrinfo = -1;
278 static int hf_smb_mac_root_file_count = -1;
279 static int hf_smb_mac_root_dir_count = -1;
280 static int hf_smb_mac_file_count = -1;
281 static int hf_smb_mac_dir_count = -1;
282 static int hf_smb_mac_support_flags = -1;
283 static int hf_smb_mac_sup_access_ctrl = -1;
284 static int hf_smb_mac_sup_getset_comments = -1;
285 static int hf_smb_mac_sup_desktopdb_calls = -1;
286 static int hf_smb_mac_sup_unique_ids = -1;
287 static int hf_smb_mac_sup_streams = -1;
288 static int hf_smb_create_dos_date = -1;
289 static int hf_smb_create_dos_time = -1;
290 static int hf_smb_last_write_time = -1;
291 static int hf_smb_last_write_dos_date = -1;
292 static int hf_smb_last_write_dos_time = -1;
293 static int hf_smb_access_time = -1;
294 static int hf_smb_access_dos_date = -1;
295 static int hf_smb_access_dos_time = -1;
296 static int hf_smb_old_file_name = -1;
297 static int hf_smb_offset = -1;
298 static int hf_smb_remaining = -1;
299 static int hf_smb_padding = -1;
300 static int hf_smb_file_data = -1;
301 static int hf_smb_total_data_len = -1;
302 static int hf_smb_data_len = -1;
303 static int hf_smb_data_len_low = -1;
304 static int hf_smb_data_len_high = -1;
305 static int hf_smb_seek_mode = -1;
306 static int hf_smb_data_size = -1;
307 static int hf_smb_alloc_size = -1;
308 static int hf_smb_alloc_size64 = -1;
309 static int hf_smb_max_count = -1;
310 static int hf_smb_max_count_low = -1;
311 static int hf_smb_max_count_high = -1;
312 static int hf_smb_min_count = -1;
313 static int hf_smb_timeout = -1;
314 static int hf_smb_high_offset = -1;
315 static int hf_smb_units = -1;
316 static int hf_smb_bpu = -1;
317 static int hf_smb_blocksize = -1;
318 static int hf_smb_freeunits = -1;
319 static int hf_smb_data_offset = -1;
320 static int hf_smb_dcm = -1;
321 static int hf_smb_request_mask = -1;
322 static int hf_smb_response_mask = -1;
323 static int hf_smb_search_id = -1;
324 static int hf_smb_write_mode_write_through = -1;
325 static int hf_smb_write_mode_return_remaining = -1;
326 static int hf_smb_write_mode_raw = -1;
327 static int hf_smb_write_mode_message_start = -1;
328 static int hf_smb_write_mode_connectionless = -1;
329 static int hf_smb_resume_key_len = -1;
330 static int hf_smb_resume_find_id = -1;
331 static int hf_smb_resume_server_cookie = -1;
332 static int hf_smb_resume_client_cookie = -1;
333 static int hf_smb_andxoffset = -1;
334 static int hf_smb_lock_type_large = -1;
335 static int hf_smb_lock_type_cancel = -1;
336 static int hf_smb_lock_type_change = -1;
337 static int hf_smb_lock_type_oplock = -1;
338 static int hf_smb_lock_type_shared = -1;
339 static int hf_smb_locking_ol = -1;
340 static int hf_smb_number_of_locks = -1;
341 static int hf_smb_number_of_unlocks = -1;
342 static int hf_smb_lock_long_offset = -1;
343 static int hf_smb_lock_long_length = -1;
344 static int hf_smb_file_type = -1;
345 static int hf_smb_ipc_state_nonblocking = -1;
346 static int hf_smb_ipc_state_endpoint = -1;
347 static int hf_smb_ipc_state_pipe_type = -1;
348 static int hf_smb_ipc_state_read_mode = -1;
349 static int hf_smb_ipc_state_icount = -1;
350 static int hf_smb_server_fid = -1;
351 static int hf_smb_open_flags_add_info = -1;
352 static int hf_smb_open_flags_ex_oplock = -1;
353 static int hf_smb_open_flags_batch_oplock = -1;
354 static int hf_smb_open_flags_ealen = -1;
355 static int hf_smb_open_action_open = -1;
356 static int hf_smb_open_action_lock = -1;
357 static int hf_smb_vc_num = -1;
358 static int hf_smb_account = -1;
359 static int hf_smb_os = -1;
360 static int hf_smb_lanman = -1;
361 static int hf_smb_setup_action_guest = -1;
362 static int hf_smb_fs = -1;
363 static int hf_smb_connect_flags_dtid = -1;
364 static int hf_smb_connect_support_search = -1;
365 static int hf_smb_connect_support_in_dfs = -1;
366 static int hf_smb_max_setup_count = -1;
367 static int hf_smb_total_param_count = -1;
368 static int hf_smb_total_data_count = -1;
369 static int hf_smb_max_param_count = -1;
370 static int hf_smb_max_data_count = -1;
371 static int hf_smb_param_disp16 = -1;
372 static int hf_smb_param_count16 = -1;
373 static int hf_smb_param_offset16 = -1;
374 static int hf_smb_param_disp32 = -1;
375 static int hf_smb_param_count32 = -1;
376 static int hf_smb_param_offset32 = -1;
377 static int hf_smb_data_disp16 = -1;
378 static int hf_smb_data_count16 = -1;
379 static int hf_smb_data_offset16 = -1;
380 static int hf_smb_data_disp32 = -1;
381 static int hf_smb_data_count32 = -1;
382 static int hf_smb_data_offset32 = -1;
383 static int hf_smb_setup_count = -1;
384 static int hf_smb_nt_trans_subcmd = -1;
385 static int hf_smb_nt_ioctl_isfsctl = -1;
386 static int hf_smb_nt_ioctl_flags_root_handle = -1;
387 #ifdef SMB_UNUSED_HANDLES
388 static int hf_smb_nt_security_information = -1;
389 #endif
390 static int hf_smb_nt_notify_action = -1;
391 static int hf_smb_nt_notify_watch_tree = -1;
392 static int hf_smb_nt_notify_stream_write = -1;
393 static int hf_smb_nt_notify_stream_size = -1;
394 static int hf_smb_nt_notify_stream_name = -1;
395 static int hf_smb_nt_notify_security = -1;
396 static int hf_smb_nt_notify_ea = -1;
397 static int hf_smb_nt_notify_creation = -1;
398 static int hf_smb_nt_notify_last_access = -1;
399 static int hf_smb_nt_notify_last_write = -1;
400 static int hf_smb_nt_notify_size = -1;
401 static int hf_smb_nt_notify_attributes = -1;
402 static int hf_smb_nt_notify_dir_name = -1;
403 static int hf_smb_nt_notify_file_name = -1;
404 static int hf_smb_root_dir_fid = -1;
405 static int hf_smb_nt_create_disposition = -1;
406 static int hf_smb_sd_length = -1;
407 static int hf_smb_ea_list_length = -1;
408 static int hf_smb_ea_flags = -1;
409 static int hf_smb_ea_name_length = -1;
410 static int hf_smb_ea_data_length = -1;
411 static int hf_smb_ea_name = -1;
412 static int hf_smb_ea_data = -1;
413 static int hf_smb_file_name_len = -1;
414 static int hf_smb_nt_impersonation_level = -1;
415 static int hf_smb_nt_security_flags_context_tracking = -1;
416 static int hf_smb_nt_security_flags_effective_only = -1;
417 static int hf_smb_nt_access_mask_generic_read = -1;
418 static int hf_smb_nt_access_mask_generic_write = -1;
419 static int hf_smb_nt_access_mask_generic_execute = -1;
420 static int hf_smb_nt_access_mask_generic_all = -1;
421 static int hf_smb_nt_access_mask_maximum_allowed = -1;
422 static int hf_smb_nt_access_mask_system_security = -1;
423 static int hf_smb_nt_access_mask_synchronize = -1;
424 static int hf_smb_nt_access_mask_write_owner = -1;
425 static int hf_smb_nt_access_mask_write_dac = -1;
426 static int hf_smb_nt_access_mask_read_control = -1;
427 static int hf_smb_nt_access_mask_delete = -1;
428 static int hf_smb_nt_access_mask_write_attributes = -1;
429 static int hf_smb_nt_access_mask_read_attributes = -1;
430 static int hf_smb_nt_access_mask_delete_child = -1;
431 static int hf_smb_nt_access_mask_execute = -1;
432 static int hf_smb_nt_access_mask_write_ea = -1;
433 static int hf_smb_nt_access_mask_read_ea = -1;
434 static int hf_smb_nt_access_mask_append = -1;
435 static int hf_smb_nt_access_mask_write = -1;
436 static int hf_smb_nt_access_mask_read = -1;
437 static int hf_smb_nt_create_bits_oplock = -1;
438 static int hf_smb_nt_create_bits_boplock = -1;
439 static int hf_smb_nt_create_bits_dir = -1;
440 static int hf_smb_nt_create_bits_ext_resp = -1;
441 static int hf_smb_nt_create_options_directory_file = -1;
442 static int hf_smb_nt_create_options_write_through = -1;
443 static int hf_smb_nt_create_options_sequential_only = -1;
444 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
445 static int hf_smb_nt_create_options_sync_io_alert = -1;
446 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
447 static int hf_smb_nt_create_options_non_directory_file = -1;
448 static int hf_smb_nt_create_options_create_tree_connection = -1;
449 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
450 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
451 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
452 static int hf_smb_nt_create_options_random_access = -1;
453 static int hf_smb_nt_create_options_delete_on_close = -1;
454 static int hf_smb_nt_create_options_open_by_fileid = -1;
455 static int hf_smb_nt_create_options_backup_intent = -1;
456 static int hf_smb_nt_create_options_no_compression = -1;
457 static int hf_smb_nt_create_options_reserve_opfilter = -1;
458 static int hf_smb_nt_create_options_open_reparse_point = -1;
459 static int hf_smb_nt_create_options_open_no_recall = -1;
460 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
461 static int hf_smb_nt_share_access_read = -1;
462 static int hf_smb_nt_share_access_write = -1;
463 static int hf_smb_nt_share_access_delete = -1;
464 static int hf_smb_file_eattr_read_only = -1;
465 static int hf_smb_file_eattr_hidden = -1;
466 static int hf_smb_file_eattr_system = -1;
467 static int hf_smb_file_eattr_volume = -1;
468 static int hf_smb_file_eattr_directory = -1;
469 static int hf_smb_file_eattr_archive = -1;
470 static int hf_smb_file_eattr_device = -1;
471 static int hf_smb_file_eattr_normal = -1;
472 static int hf_smb_file_eattr_temporary = -1;
473 static int hf_smb_file_eattr_sparse = -1;
474 static int hf_smb_file_eattr_reparse = -1;
475 static int hf_smb_file_eattr_compressed = -1;
476 static int hf_smb_file_eattr_offline = -1;
477 static int hf_smb_file_eattr_not_content_indexed = -1;
478 static int hf_smb_file_eattr_encrypted = -1;
479 static int hf_smb_sec_desc_len = -1;
480 static int hf_smb_nt_qsd_owner = -1;
481 static int hf_smb_nt_qsd_group = -1;
482 static int hf_smb_nt_qsd_dacl = -1;
483 static int hf_smb_nt_qsd_sacl = -1;
484 static int hf_smb_extended_attributes = -1;
485 static int hf_smb_oplock_level = -1;
486 static int hf_smb_create_action = -1;
487 static int hf_smb_file_id = -1;
488 static int hf_smb_ea_error_offset = -1;
489 static int hf_smb_end_of_file = -1;
490 static int hf_smb_replace = -1;
491 static int hf_smb_root_dir_handle = -1;
492 static int hf_smb_target_name_len = -1;
493 static int hf_smb_target_name = -1;
494 static int hf_smb_device_type = -1;
495 static int hf_smb_is_directory = -1;
496 static int hf_smb_next_entry_offset = -1;
497 static int hf_smb_change_time = -1;
498 static int hf_smb_setup_len = -1;
499 static int hf_smb_print_mode = -1;
500 static int hf_smb_print_identifier = -1;
501 static int hf_smb_restart_index = -1;
502 static int hf_smb_print_queue_date = -1;
503 static int hf_smb_print_queue_dos_date = -1;
504 static int hf_smb_print_queue_dos_time = -1;
505 static int hf_smb_print_status = -1;
506 static int hf_smb_print_spool_file_number = -1;
507 static int hf_smb_print_spool_file_size = -1;
508 static int hf_smb_print_spool_file_name = -1;
509 static int hf_smb_start_index = -1;
510 static int hf_smb_originator_name = -1;
511 static int hf_smb_destination_name = -1;
512 static int hf_smb_message_len = -1;
513 static int hf_smb_message = -1;
514 static int hf_smb_mgid = -1;
515 static int hf_smb_forwarded_name = -1;
516 static int hf_smb_machine_name = -1;
517 static int hf_smb_cancel_to = -1;
518 static int hf_smb_trans2_subcmd = -1;
519 static int hf_smb_trans_name = -1;
520 static int hf_smb_transaction_flags_dtid = -1;
521 static int hf_smb_transaction_flags_owt = -1;
522 static int hf_smb_search_count = -1;
523 static int hf_smb_search_pattern = -1;
524 static int hf_smb_ff2_backup = -1;
525 static int hf_smb_ff2_continue = -1;
526 static int hf_smb_ff2_resume = -1;
527 static int hf_smb_ff2_close_eos = -1;
528 static int hf_smb_ff2_close = -1;
529 static int hf_smb_ff2_information_level = -1;
530 static int hf_smb_qpi_loi = -1;
531 static int hf_smb_spi_loi = -1;
532 #if 0
533 static int hf_smb_sfi_writetru = -1;
534 static int hf_smb_sfi_caching = -1;
535 #endif
536 static int hf_smb_storage_type = -1;
537 static int hf_smb_resume = -1;
538 static int hf_smb_max_referral_level = -1;
539 static int hf_smb_qfsi_information_level = -1;
540 static int hf_smb_number_of_links = -1;
541 static int hf_smb_delete_pending = -1;
542 static int hf_smb_index_number = -1;
543 static int hf_smb_position = -1;
544 static int hf_smb_current_offset = -1;
545 static int hf_smb_t2_alignment = -1;
546 static int hf_smb_t2_stream_name_length = -1;
547 static int hf_smb_t2_stream_size = -1;
548 static int hf_smb_t2_stream_name = -1;
549 static int hf_smb_t2_compressed_file_size = -1;
550 static int hf_smb_t2_compressed_format = -1;
551 static int hf_smb_t2_compressed_unit_shift = -1;
552 static int hf_smb_t2_compressed_chunk_shift = -1;
553 static int hf_smb_t2_compressed_cluster_shift = -1;
554 static int hf_smb_t2_marked_for_deletion = -1;
555 static int hf_smb_dfs_path_consumed = -1;
556 static int hf_smb_dfs_num_referrals = -1;
557 static int hf_smb_get_dfs_server_hold_storage = -1;
558 static int hf_smb_get_dfs_fielding = -1;
559 static int hf_smb_dfs_referral_version = -1;
560 static int hf_smb_dfs_referral_size = -1;
561 static int hf_smb_dfs_referral_server_type = -1;
562 static int hf_smb_dfs_referral_flags_strip = -1;
563 static int hf_smb_dfs_referral_node_offset = -1;
564 static int hf_smb_dfs_referral_node = -1;
565 static int hf_smb_dfs_referral_proximity = -1;
566 static int hf_smb_dfs_referral_ttl = -1;
567 static int hf_smb_dfs_referral_path_offset = -1;
568 static int hf_smb_dfs_referral_path = -1;
569 static int hf_smb_dfs_referral_alt_path_offset = -1;
570 static int hf_smb_dfs_referral_alt_path = -1;
571 static int hf_smb_end_of_search = -1;
572 static int hf_smb_last_name_offset = -1;
573 static int hf_smb_fn_information_level = -1;
574 static int hf_smb_monitor_handle = -1;
575 static int hf_smb_change_count = -1;
576 static int hf_smb_file_index = -1;
577 static int hf_smb_short_file_name = -1;
578 static int hf_smb_short_file_name_len = -1;
579 static int hf_smb_fs_id = -1;
580 static int hf_smb_sector_unit = -1;
581 static int hf_smb_fs_units = -1;
582 static int hf_smb_fs_sector = -1;
583 static int hf_smb_avail_units = -1;
584 static int hf_smb_volume_serial_num = -1;
585 static int hf_smb_volume_label_len = -1;
586 static int hf_smb_volume_label = -1;
587 static int hf_smb_free_alloc_units64 = -1;
588 static int hf_smb_caller_free_alloc_units64 = -1;
589 static int hf_smb_actual_free_alloc_units64 = -1;
590 static int hf_smb_max_name_len = -1;
591 static int hf_smb_fs_name_len = -1;
592 static int hf_smb_fs_name = -1;
593 static int hf_smb_device_char_removable = -1;
594 static int hf_smb_device_char_read_only = -1;
595 static int hf_smb_device_char_floppy = -1;
596 static int hf_smb_device_char_write_once = -1;
597 static int hf_smb_device_char_remote = -1;
598 static int hf_smb_device_char_mounted = -1;
599 static int hf_smb_device_char_virtual = -1;
600 static int hf_smb_fs_attr_css = -1;
601 static int hf_smb_fs_attr_cpn = -1;
602 static int hf_smb_fs_attr_uod = -1;
603 static int hf_smb_fs_attr_pacls = -1;
604 static int hf_smb_fs_attr_fc = -1;
605 static int hf_smb_fs_attr_vq = -1;
606 static int hf_smb_fs_attr_ssf = -1;
607 static int hf_smb_fs_attr_srp = -1;
608 static int hf_smb_fs_attr_srs = -1;
609 static int hf_smb_fs_attr_sla = -1;
610 static int hf_smb_fs_attr_vic = -1;
611 static int hf_smb_fs_attr_soids = -1;
612 static int hf_smb_fs_attr_se = -1;
613 static int hf_smb_fs_attr_ns = -1;
614 static int hf_smb_fs_attr_rov = -1;
615 static int hf_smb_quota_flags_enabled = -1;
616 static int hf_smb_quota_flags_deny_disk = -1;
617 static int hf_smb_quota_flags_log_limit = -1;
618 static int hf_smb_quota_flags_log_warning = -1;
619 static int hf_smb_soft_quota_limit = -1;
620 static int hf_smb_hard_quota_limit = -1;
621 static int hf_smb_user_quota_used = -1;
622 static int hf_smb_user_quota_offset = -1;
623 static int hf_smb_nt_rename_level = -1;
624 static int hf_smb_cluster_count = -1;
625 static int hf_smb_segments = -1;
626 static int hf_smb_segment = -1;
627 static int hf_smb_segment_overlap = -1;
628 static int hf_smb_segment_overlap_conflict = -1;
629 static int hf_smb_segment_multiple_tails = -1;
630 static int hf_smb_segment_too_long_fragment = -1;
631 static int hf_smb_segment_error = -1;
632 static int hf_smb_pipe_write_len = -1;
633 static int hf_smb_unix_major_version = -1;
634 static int hf_smb_unix_minor_version = -1;
635 static int hf_smb_unix_capability_fcntl = -1;
636 static int hf_smb_unix_capability_posix_acl = -1;
637 static int hf_smb_unix_file_size = -1;
638 static int hf_smb_unix_file_num_bytes = -1;
639 static int hf_smb_unix_file_last_status = -1;
640 static int hf_smb_unix_file_last_access = -1;
641 static int hf_smb_unix_file_last_change = -1;
642 static int hf_smb_unix_file_uid = -1;
643 static int hf_smb_unix_file_gid = -1;
644 static int hf_smb_unix_file_type = -1;
645 static int hf_smb_unix_file_dev_major = -1;
646 static int hf_smb_unix_file_dev_minor = -1;
647 static int hf_smb_unix_file_unique_id = -1;
648 static int hf_smb_unix_file_permissions = -1;
649 static int hf_smb_unix_file_nlinks = -1;
650 static int hf_smb_unix_file_link_dest = -1;
651 static int hf_smb_unix_find_file_nextoffset = -1;
652 static int hf_smb_unix_find_file_resumekey = -1;
653 static int hf_smb_network_unknown = -1;
654 static int hf_smb_disposition_delete_on_close = -1;
655 static int hf_smb_pipe_info_flag = -1;
656 static int hf_smb_mode = -1;
657 static int hf_smb_attribute = -1;
658 static int hf_smb_reparse_tag = -1;
659 static int hf_smb_logged_in = -1;
660 static int hf_smb_logged_out = -1;
661 static int hf_smb_file_rw_offset = -1;
662 static int hf_smb_file_rw_length = -1;
663
664 static gint ett_smb = -1;
665 static gint ett_smb_fid = -1;
666 static gint ett_smb_tid = -1;
667 static gint ett_smb_uid = -1;
668 static gint ett_smb_hdr = -1;
669 static gint ett_smb_command = -1;
670 static gint ett_smb_fileattributes = -1;
671 static gint ett_smb_capabilities = -1;
672 static gint ett_smb_aflags = -1;
673 static gint ett_smb_dialect = -1;
674 static gint ett_smb_dialects = -1;
675 static gint ett_smb_mode = -1;
676 static gint ett_smb_rawmode = -1;
677 static gint ett_smb_flags = -1;
678 static gint ett_smb_flags2 = -1;
679 static gint ett_smb_desiredaccess = -1;
680 static gint ett_smb_search = -1;
681 static gint ett_smb_file = -1;
682 static gint ett_smb_openfunction = -1;
683 static gint ett_smb_filetype = -1;
684 static gint ett_smb_openaction = -1;
685 static gint ett_smb_writemode = -1;
686 static gint ett_smb_lock_type = -1;
687 static gint ett_smb_ssetupandxaction = -1;
688 static gint ett_smb_optionsup = -1;
689 static gint ett_smb_time_date = -1;
690 static gint ett_smb_move_copy_flags = -1;
691 static gint ett_smb_file_attributes = -1;
692 static gint ett_smb_search_resume_key = -1;
693 static gint ett_smb_search_dir_info = -1;
694 static gint ett_smb_unlocks = -1;
695 static gint ett_smb_unlock = -1;
696 static gint ett_smb_locks = -1;
697 static gint ett_smb_lock = -1;
698 static gint ett_smb_open_flags = -1;
699 static gint ett_smb_ipc_state = -1;
700 static gint ett_smb_open_action = -1;
701 static gint ett_smb_setup_action = -1;
702 static gint ett_smb_connect_flags = -1;
703 static gint ett_smb_connect_support_bits = -1;
704 static gint ett_smb_nt_access_mask = -1;
705 static gint ett_smb_nt_create_bits = -1;
706 static gint ett_smb_nt_create_options = -1;
707 static gint ett_smb_nt_share_access = -1;
708 static gint ett_smb_nt_security_flags = -1;
709 static gint ett_smb_nt_trans_setup = -1;
710 static gint ett_smb_nt_trans_data = -1;
711 static gint ett_smb_nt_trans_param = -1;
712 static gint ett_smb_nt_notify_completion_filter = -1;
713 static gint ett_smb_nt_ioctl_flags = -1;
714 static gint ett_smb_security_information_mask = -1;
715 static gint ett_smb_print_queue_entry = -1;
716 static gint ett_smb_transaction_flags = -1;
717 static gint ett_smb_transaction_params = -1;
718 static gint ett_smb_find_first2_flags = -1;
719 static gint ett_smb_mac_support_flags = -1;
720 #if 0
721 static gint ett_smb_ioflag = -1;
722 #endif
723 static gint ett_smb_transaction_data = -1;
724 static gint ett_smb_stream_info = -1;
725 static gint ett_smb_dfs_referrals = -1;
726 static gint ett_smb_dfs_referral = -1;
727 static gint ett_smb_dfs_referral_flags = -1;
728 static gint ett_smb_get_dfs_flags = -1;
729 static gint ett_smb_ff2_data = -1;
730 static gint ett_smb_device_characteristics = -1;
731 static gint ett_smb_fs_attributes = -1;
732 static gint ett_smb_segments = -1;
733 static gint ett_smb_segment = -1;
734 static gint ett_smb_quotaflags = -1;
735 static gint ett_smb_secblob = -1;
736 static gint ett_smb_unicode_password = -1;
737 static gint ett_smb_ea = -1;
738 static gint ett_smb_unix_capabilities = -1;
739
740 static int smb_tap = -1;
741
742 static dissector_handle_t gssapi_handle = NULL;
743 static dissector_handle_t ntlmssp_handle = NULL;
744
745 static const fragment_items smb_frag_items = {
746         &ett_smb_segment,
747         &ett_smb_segments,
748
749         &hf_smb_segments,
750         &hf_smb_segment,
751         &hf_smb_segment_overlap,
752         &hf_smb_segment_overlap_conflict,
753         &hf_smb_segment_multiple_tails,
754         &hf_smb_segment_too_long_fragment,
755         &hf_smb_segment_error,
756         NULL,
757
758         "segments"
759 };
760
761 static proto_tree *top_tree=NULL;     /* ugly */
762
763 static const char *decode_smb_name(guint8);
764 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
765
766 /*
767  * Macros for use in the main dissector routines for an SMB.
768  */
769
770 #define WORD_COUNT      \
771         /* Word Count */                                \
772         wc = tvb_get_guint8(tvb, offset);               \
773         proto_tree_add_uint(tree, hf_smb_word_count,    \
774                 tvb, offset, 1, wc);                    \
775         offset += 1;                                    \
776         if(wc==0) goto bytecount;
777
778 #define BYTE_COUNT      \
779         bytecount:                                      \
780         bc = tvb_get_letohs(tvb, offset);               \
781         proto_tree_add_uint(tree, hf_smb_byte_count,    \
782                         tvb, offset, 2, bc);            \
783         offset += 2;                                    \
784         if(bc==0) goto endofcommand;
785
786 #define CHECK_BYTE_COUNT(len)   \
787         if (bc < len) goto endofcommand;
788
789 #define COUNT_BYTES(len)   {\
790         int tmp;            \
791         tmp=len;            \
792         offset += tmp;      \
793         bc -= tmp;          \
794         }
795
796 #define END_OF_SMB      \
797         if (bc != 0) { \
798                 gint bc_remaining; \
799                 bc_remaining=tvb_length_remaining(tvb, offset); \
800                 if( ((gint)bc) > bc_remaining){ \
801                         bc=bc_remaining; \
802                 } \
803                 if(bc){ \
804                         tvb_ensure_bytes_exist(tvb, offset, bc); \
805                         proto_tree_add_text(tree, tvb, offset, bc, \
806                             "Extra byte parameters");           \
807                 } \
808                 offset += bc;                           \
809         }                                               \
810         endofcommand:
811
812 /*
813  * Macros for use in routines called by them.
814  */
815 #define CHECK_BYTE_COUNT_SUBR(len)      \
816         if (*bcp < len) {               \
817                 *trunc = TRUE;          \
818                 return offset;          \
819         }
820
821 #define CHECK_STRING_SUBR(fn)   \
822         if (fn == NULL) {       \
823                 *trunc = TRUE;  \
824                 return offset;  \
825         }
826
827 #define COUNT_BYTES_SUBR(len)   \
828         offset += len;          \
829         *bcp -= len;
830
831 /*
832  * Macros for use when dissecting transaction parameters and data
833  */
834 #define CHECK_BYTE_COUNT_TRANS(len)     \
835         if (bc < len) return offset;
836
837 #define CHECK_STRING_TRANS(fn)  \
838         if (fn == NULL) return offset;
839
840 #define COUNT_BYTES_TRANS(len)  \
841         offset += len;          \
842         bc -= len;
843
844 /*
845  * Macros for use in subrroutines dissecting transaction parameters or data
846  */
847 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
848         if (*bcp < len) return offset;
849
850 #define CHECK_STRING_TRANS_SUBR(fn)     \
851         if (fn == NULL) return offset;
852
853 #define COUNT_BYTES_TRANS_SUBR(len)     \
854         offset += len;                  \
855         *bcp -= len;
856
857
858 gboolean sid_name_snooping = FALSE;
859
860 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
861    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
862    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
863 static gboolean smb_trans_reassembly = TRUE;
864 gboolean smb_dcerpc_reassembly = TRUE;
865
866 static GHashTable *smb_trans_fragment_table = NULL;
867
868 static void
869 smb_trans_reassembly_init(void)
870 {
871         fragment_table_init(&smb_trans_fragment_table);
872 }
873
874 /*
875  * XXX - This keeps us from allocating huge amounts of memory as shown in
876  * bug 421.  It may need to be increased.
877  */
878 #define MAX_FRAGMENT_SIZE 65536
879 static fragment_data *
880 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
881                      int offset, int count, int pos, int totlen)
882 {
883         fragment_data *fd_head=NULL;
884         smb_info_t *si;
885         int more_frags;
886
887         if (count > MAX_FRAGMENT_SIZE || count < 0) {
888                 THROW(ReportedBoundsError);
889         }
890
891         more_frags=totlen>(pos+count);
892
893         si = (smb_info_t *)pinfo->private_data;
894         DISSECTOR_ASSERT(si);
895
896         if (si->sip == NULL) {
897                 /*
898                  * We don't have the frame number of the request.
899                  */
900                 return NULL;
901         }
902
903         if(!pinfo->fd->flags.visited){
904                 fd_head = fragment_add(tvb, offset, pinfo,
905                                        si->sip->frame_req, smb_trans_fragment_table,
906                                        pos, count, more_frags);
907         } else {
908                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
909         }
910
911         if (!fd_head || !(fd_head->flags&FD_DEFRAGMENTED)){
912                 /* This is continued - mark it as such, so we recognize
913                    continuation responses.
914                 */
915                 si->sip->flags |= SMB_SIF_IS_CONTINUED;
916         } else {
917                 /* We've finished reassembling, so there are no more
918                    continuation responses.
919                 */
920                 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
921         }
922
923         /* we only show the defragmented packet for the first fragment,
924            or else we might end up with dissecting one HUGE transaction PDU
925            a LOT of times. (first fragment is the only one containing the setup
926            bytes)
927            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
928            SMBs. Takes a LOT of time dissecting and is not fun.
929         */
930         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
931                 return fd_head;
932         } else {
933                 return NULL;
934         }
935 }
936
937
938
939
940
941 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
942    These variables and functions are used to match
943    responses with calls
944    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
945 /*
946  * The information we need to save about a request in order to show the
947  * frame number of the request in the dissection of the reply.
948  */
949 typedef struct  {
950         guint32 frame;
951         guint32 pid_mid;
952 } smb_saved_info_key_t;
953
954 /* unmatched smb_saved_info structures.
955    For unmatched smb_saved_info structures we store the smb_saved_info
956    structure using the MID and the PID as the key.
957
958    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
959    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
960    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
961 */
962 static gint
963 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
964 {
965         register guint32 key1 = GPOINTER_TO_UINT(k1);
966         register guint32 key2 = GPOINTER_TO_UINT(k2);
967         return key1==key2;
968 }
969 static guint
970 smb_saved_info_hash_unmatched(gconstpointer k)
971 {
972         register guint32 key = GPOINTER_TO_UINT(k);
973         return key;
974 }
975
976 /* matched smb_saved_info structures.
977    For matched smb_saved_info structures we store the smb_saved_info
978    structure twice in the table using the frame number, and a combination
979    of the MID and the PID, as the key.
980    The frame number is guaranteed to be unique but if ever someone makes
981    some change that will renumber the frames in a capture we are in BIG trouble.
982    This is not likely though since that would break (among other things) all the
983    reassembly routines as well.
984
985    We also need the MID as there may be more than one SMB request or reply
986    in a single frame, and we also need the PID as there may be more than
987    one outstanding request with the same MID and different PIDs.
988 */
989 static gint
990 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
991 {
992         const smb_saved_info_key_t *key1 = k1;
993         const smb_saved_info_key_t *key2 = k2;
994         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
995 }
996 static guint
997 smb_saved_info_hash_matched(gconstpointer k)
998 {
999         const smb_saved_info_key_t *key = k;
1000         return key->frame + key->pid_mid;
1001 }
1002
1003 static GSList *conv_tables = NULL;
1004
1005
1006 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1007    End of request/response matching functions
1008    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1009
1010
1011
1012 typedef struct _smb_uid_t {
1013         char *domain;
1014         char *account;
1015         int logged_in;
1016         int logged_out;
1017 } smb_uid_t;
1018
1019 static void
1020 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1021 {
1022         mask&=0x0000ffff;
1023         if(mask==0x000001ff){
1024                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1025         }
1026
1027
1028         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1029         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1030         proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1031         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1032         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1033         proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1034         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1035         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1036 }
1037 struct access_mask_info smb_file_access_mask_info = {
1038         "FILE",                         /* Name of specific rights */
1039         smb_file_specific_rights,       /* Dissection function */
1040         NULL,                           /* Generic mapping table */
1041         NULL                            /* Standard mapping table */
1042 };
1043
1044
1045 static void
1046 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1047 {
1048         mask&=0x0000ffff;
1049         if(mask==0x000001ff){
1050                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1051         }
1052
1053
1054         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1055         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1056         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1057         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1058         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1059         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1060         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1061         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1062         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1063 }
1064 struct access_mask_info smb_dir_access_mask_info = {
1065         "DIR",                          /* Name of specific rights */
1066         smb_dir_specific_rights,        /* Dissection function */
1067         NULL,                           /* Generic mapping table */
1068         NULL                            /* Standard mapping table */
1069 };
1070
1071
1072
1073 static const value_string buffer_format_vals[] = {
1074         {1,     "Data Block"},
1075         {2,     "Dialect"},
1076         {3,     "Pathname"},
1077         {4,     "ASCII"},
1078         {5,     "Variable Block"},
1079         {0,     NULL}
1080 };
1081
1082 /*
1083  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1084  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1085  * January 1, 1970, 00:00:00 GMT.
1086  *
1087  * This means we have to do some extra work to convert it.  This code is
1088  * based on the Samba code:
1089  *
1090  *      Unix SMB/Netbios implementation.
1091  *      Version 1.9.
1092  *      time handling functions
1093  *      Copyright (C) Andrew Tridgell 1992-1998
1094  */
1095
1096 /*
1097  * Yield the difference between *A and *B, in seconds, ignoring leap
1098  * seconds.
1099  */
1100 #define TM_YEAR_BASE 1900
1101
1102 static int
1103 tm_diff(struct tm *a, struct tm *b)
1104 {
1105         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1106         int by = b->tm_year + (TM_YEAR_BASE - 1);
1107         int intervening_leap_days =
1108             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1109         int years = ay - by;
1110         int days =
1111             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1112         int hours = 24*days + (a->tm_hour - b->tm_hour);
1113         int minutes = 60*hours + (a->tm_min - b->tm_min);
1114         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1115
1116         return seconds;
1117 }
1118
1119 /*
1120  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1121  * determined.
1122  */
1123 static int
1124 TimeZone(time_t t)
1125 {
1126         struct tm *tm = gmtime(&t);
1127         struct tm tm_utc;
1128
1129         if (tm == NULL)
1130                 return 0;
1131         tm_utc = *tm;
1132         tm = localtime(&t);
1133         if (tm == NULL)
1134                 return 0;
1135         return tm_diff(&tm_utc,tm);
1136 }
1137
1138 /*
1139  * Return the same value as TimeZone, but it should be more efficient.
1140  *
1141  * We keep a table of DST offsets to prevent calling localtime() on each
1142  * call of this function. This saves a LOT of time on many unixes.
1143  *
1144  * Updated by Paul Eggert <eggert@twinsun.com>
1145  */
1146 #ifndef CHAR_BIT
1147 #define CHAR_BIT 8
1148 #endif
1149
1150 #ifndef TIME_T_MIN
1151 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1152                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1153 #endif
1154 #ifndef TIME_T_MAX
1155 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1156 #endif
1157
1158 static int
1159 TimeZoneFaster(time_t t)
1160 {
1161         static struct dst_table {time_t start,end; int zone;} *tdt;
1162         static struct dst_table *dst_table = NULL;
1163         static int table_size = 0;
1164         int i;
1165         int zone = 0;
1166
1167         if (t == 0)
1168                 t = time(NULL);
1169
1170         /* Tunis has a 8 day DST region, we need to be careful ... */
1171 #define MAX_DST_WIDTH (365*24*60*60)
1172 #define MAX_DST_SKIP (7*24*60*60)
1173
1174         for (i = 0; i < table_size; i++) {
1175                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1176                         break;
1177         }
1178
1179         if (i < table_size) {
1180                 zone = dst_table[i].zone;
1181         } else {
1182                 time_t low,high;
1183
1184                 zone = TimeZone(t);
1185                 if (dst_table == NULL)
1186                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1187                 else
1188                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1189                 if (tdt == NULL) {
1190                         if (dst_table)
1191                                 g_free(dst_table);
1192                         table_size = 0;
1193                 } else {
1194                         dst_table = tdt;
1195                         table_size++;
1196
1197                         dst_table[i].zone = zone;
1198                         dst_table[i].start = dst_table[i].end = t;
1199
1200                         /* no entry will cover more than 6 months */
1201                         low = t - MAX_DST_WIDTH/2;
1202                         if (t < low)
1203                                 low = TIME_T_MIN;
1204
1205                         high = t + MAX_DST_WIDTH/2;
1206                         if (high < t)
1207                                 high = TIME_T_MAX;
1208
1209                         /*
1210                          * Widen the new entry using two bisection searches.
1211                          */
1212                         while (low+60*60 < dst_table[i].start) {
1213                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1214                                         t = dst_table[i].start - MAX_DST_SKIP;
1215                                 else
1216                                         t = low + (dst_table[i].start-low)/2;
1217                                 if (TimeZone(t) == zone)
1218                                         dst_table[i].start = t;
1219                                 else
1220                                         low = t;
1221                         }
1222
1223                         while (high-60*60 > dst_table[i].end) {
1224                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1225                                         t = dst_table[i].end + MAX_DST_SKIP;
1226                                 else
1227                                         t = high - (high-dst_table[i].end)/2;
1228                                 if (TimeZone(t) == zone)
1229                                         dst_table[i].end = t;
1230                                 else
1231                                         high = t;
1232                         }
1233                 }
1234         }
1235         return zone;
1236 }
1237
1238 /*
1239  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1240  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1241  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1242  * daylight savings transitions because some local times are ambiguous.
1243  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1244  */
1245 static int
1246 LocTimeDiff(time_t lt)
1247 {
1248         int d = TimeZoneFaster(lt);
1249         time_t t = lt + d;
1250
1251         /* if overflow occurred, ignore all the adjustments so far */
1252         if (((t < lt) ^ (d < 0)))
1253                 t = lt;
1254
1255         /*
1256          * Now t should be close enough to the true UTC to yield the
1257          * right answer.
1258          */
1259         return TimeZoneFaster(t);
1260 }
1261
1262 static int
1263 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1264 {
1265         guint32 timeval;
1266         nstime_t ts;
1267
1268         timeval = tvb_get_letohl(tvb, offset);
1269         if (timeval == 0xffffffff) {
1270                 proto_tree_add_text(tree, tvb, offset, 4,
1271                     "%s: No time specified (0xffffffff)",
1272                     proto_registrar_get_name(hf_date));
1273                 offset += 4;
1274                 return offset;
1275         }
1276
1277         /*
1278          * We add the local time offset.
1279          */
1280         ts.secs = timeval + LocTimeDiff(timeval);
1281         ts.nsecs = 0;
1282
1283         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1284         offset += 4;
1285
1286         return offset;
1287 }
1288
1289 static int
1290 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1291     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1292 {
1293         guint16 dos_time, dos_date;
1294         proto_item *item = NULL;
1295         proto_tree *tree = NULL;
1296         struct tm tm;
1297         time_t t;
1298         static const int mday_noleap[12] = {
1299                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1300         };
1301         static const int mday_leap[12] = {
1302                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1303         };
1304 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1305         nstime_t tv;
1306
1307         if (time_first) {
1308                 dos_time = tvb_get_letohs(tvb, offset);
1309                 dos_date = tvb_get_letohs(tvb, offset+2);
1310         } else {
1311                 dos_date = tvb_get_letohs(tvb, offset);
1312                 dos_time = tvb_get_letohs(tvb, offset+2);
1313         }
1314
1315         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1316             (dos_date == 0 && dos_time == 0)) {
1317                 /*
1318                  * No date/time specified.
1319                  */
1320                 if(parent_tree){
1321                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1322                             "%s: No time specified (0x%08x)",
1323                             proto_registrar_get_name(hf_date),
1324                             (dos_date << 16) | dos_time);
1325                 }
1326                 offset += 4;
1327                 return offset;
1328         }
1329
1330         tm.tm_sec = (dos_time&0x1f)*2;
1331         tm.tm_min = (dos_time>>5)&0x3f;
1332         tm.tm_hour = (dos_time>>11)&0x1f;
1333         tm.tm_mday = dos_date&0x1f;
1334         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1335         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1336         tm.tm_isdst = -1;
1337
1338         /*
1339          * Do some sanity checks before calling "mktime()";
1340          * "mktime()" doesn't do them, it "normalizes" out-of-range
1341          * values.
1342          */
1343         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1344            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1345            (ISLEAP(tm.tm_year + 1900) ?
1346              tm.tm_mday > mday_leap[tm.tm_mon] :
1347              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1348              (t = mktime(&tm)) == -1) {
1349                 /*
1350                  * Invalid date/time.
1351                  */
1352                 if (parent_tree) {
1353                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1354                             "%s: Invalid time",
1355                             proto_registrar_get_name(hf_date));
1356                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1357                         if (time_first) {
1358                                 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);
1359                                 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);
1360                         } else {
1361                                 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);
1362                                 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);
1363                         }
1364                 }
1365                 offset += 4;
1366                 return offset;
1367         }
1368
1369         tv.secs = t;
1370         tv.nsecs = 0;
1371
1372         if(parent_tree){
1373                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1374                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1375                 if (time_first) {
1376                         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);
1377                         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);
1378                 } else {
1379                         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);
1380                         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);
1381                 }
1382         }
1383
1384         offset += 4;
1385
1386         return offset;
1387 }
1388
1389 static const true_false_string tfs_disposition_delete_on_close = {
1390         "DELETE this file when closed",
1391         "Normal access, do not delete on close"
1392 };
1393
1394 static const true_false_string tfs_pipe_info_flag = {
1395         "SET NAMED PIPE mode",
1396         "Clear NAMED PIPE mode"
1397 };
1398
1399
1400 static const value_string da_access_vals[] = {
1401         { 0,            "Open for reading"},
1402         { 1,            "Open for writing"},
1403         { 2,            "Open for reading and writing"},
1404         { 3,            "Open for execute"},
1405         {0, NULL}
1406 };
1407 static const value_string da_sharing_vals[] = {
1408         { 0,            "Compatibility mode"},
1409         { 1,            "Deny read/write/execute (exclusive)"},
1410         { 2,            "Deny write"},
1411         { 3,            "Deny read/execute"},
1412         { 4,            "Deny none"},
1413         {0, NULL}
1414 };
1415 static const value_string da_locality_vals[] = {
1416         { 0,            "Locality of reference unknown"},
1417         { 1,            "Mainly sequential access"},
1418         { 2,            "Mainly random access"},
1419         { 3,            "Random access with some locality"},
1420         {0, NULL}
1421 };
1422 static const true_false_string tfs_da_caching = {
1423         "Do not cache this file",
1424         "Caching permitted on this file"
1425 };
1426 static const true_false_string tfs_da_writetru = {
1427         "Write through enabled",
1428         "Write through disabled"
1429 };
1430 static int
1431 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1432 {
1433         guint16 mask;
1434         proto_item *item = NULL;
1435         proto_tree *tree = NULL;
1436
1437         mask = tvb_get_letohs(tvb, offset);
1438
1439         if(parent_tree){
1440                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1441                         "%s Access: 0x%04x", type, mask);
1442                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1443         }
1444
1445         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1446                 tvb, offset, 2, mask);
1447         proto_tree_add_boolean(tree, hf_smb_access_caching,
1448                 tvb, offset, 2, mask);
1449         proto_tree_add_uint(tree, hf_smb_access_locality,
1450                 tvb, offset, 2, mask);
1451         proto_tree_add_uint(tree, hf_smb_access_sharing,
1452                 tvb, offset, 2, mask);
1453         proto_tree_add_uint(tree, hf_smb_access_mode,
1454                 tvb, offset, 2, mask);
1455
1456         offset += 2;
1457
1458         return offset;
1459 }
1460
1461 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1462 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1463 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1464 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1465 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1466 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1467 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1468 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1469 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1470 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1471 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1472 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1473 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1474 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1475 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1476
1477 static const true_false_string tfs_file_attribute_read_only = {
1478         "This file is READ ONLY",
1479         "This file is NOT read only",
1480 };
1481 static const true_false_string tfs_file_attribute_hidden = {
1482         "This is a HIDDEN file",
1483         "This is NOT a hidden file"
1484 };
1485 static const true_false_string tfs_file_attribute_system = {
1486         "This is a SYSTEM file",
1487         "This is NOT a system file"
1488 };
1489 static const true_false_string tfs_file_attribute_volume = {
1490         "This is a VOLUME ID",
1491         "This is NOT a volume ID"
1492 };
1493 static const true_false_string tfs_file_attribute_directory = {
1494         "This is a DIRECTORY",
1495         "This is NOT a directory"
1496 };
1497 static const true_false_string tfs_file_attribute_archive = {
1498         "This file has been modified since last ARCHIVE",
1499         "This file has NOT been modified since last archive"
1500 };
1501 static const true_false_string tfs_file_attribute_device = {
1502         "This is a DEVICE",
1503         "This is NOT a device"
1504 };
1505 static const true_false_string tfs_file_attribute_normal = {
1506         "This file is an ordinary file",
1507         "This file has some attribute set"
1508 };
1509 static const true_false_string tfs_file_attribute_temporary = {
1510         "This is a TEMPORARY file",
1511         "This is NOT a temporary file"
1512 };
1513 static const true_false_string tfs_file_attribute_sparse = {
1514         "This is a SPARSE file",
1515         "This is NOT a sparse file"
1516 };
1517 static const true_false_string tfs_file_attribute_reparse = {
1518         "This file has an associated REPARSE POINT",
1519         "This file does NOT have an associated reparse point"
1520 };
1521 static const true_false_string tfs_file_attribute_compressed = {
1522         "This is a COMPRESSED file",
1523         "This is NOT a compressed file"
1524 };
1525 static const true_false_string tfs_file_attribute_offline = {
1526         "This file is OFFLINE",
1527         "This file is NOT offline"
1528 };
1529 static const true_false_string tfs_file_attribute_not_content_indexed = {
1530         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1531         "This file MAY be indexed by the content indexing service"
1532 };
1533 static const true_false_string tfs_file_attribute_encrypted = {
1534         "This is an ENCRYPTED file",
1535         "This is NOT an encrypted file"
1536 };
1537
1538 /*
1539  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1540  * listed as USHORT, and seem to be in packets in the wild, while in other
1541  * places they are listed as ULONG, and also seem to be.
1542  *
1543  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1544  * bytes to consume.
1545  */
1546
1547 int
1548 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1549                         int bytes)
1550 {
1551         guint16 mask;
1552         proto_item *item = NULL;
1553         proto_tree *tree = NULL;
1554
1555         if (bytes != 2 && bytes != 4) {
1556                 THROW(ReportedBoundsError);
1557         }
1558
1559         /*
1560          * The actual bits of interest appear to only be a USHORT
1561          */
1562         /* FIXME if this ever changes! */
1563         mask = tvb_get_letohs(tvb, offset);
1564
1565         if(parent_tree){
1566                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1567                         "File Attributes: 0x%08x", mask);
1568                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1569         }
1570         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1571                                tvb, offset, bytes, mask);       
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1573                                tvb, offset, bytes, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1575                                tvb, offset, bytes, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1577                                tvb, offset, bytes, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1579                                tvb, offset, bytes, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1581                                tvb, offset, bytes, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1583                                tvb, offset, bytes, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1585                                tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1587                                tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1589                 tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1591                 tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1593                 tvb, offset, bytes, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1595                 tvb, offset, bytes, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1597                 tvb, offset, bytes, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1599                 tvb, offset, bytes, mask);
1600
1601         offset += bytes;
1602
1603         return offset;
1604 }
1605
1606 /* 3.11 */
1607 static int
1608 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1609     int len, guint32 mask)
1610 {
1611         proto_item *item = NULL;
1612         proto_tree *tree = NULL;
1613
1614         if(parent_tree){
1615                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
1616                         "File Attributes: 0x%08x", mask);
1617                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1618         }
1619
1620         /*
1621          * XXX - Network Monitor disagrees on some of the
1622          * bits, e.g. the bits above temporary are "atomic write"
1623          * and "transaction write", and it says nothing about the
1624          * bits above that.
1625          *
1626          * Does the Win32 API documentation, or the NT Native API book,
1627          * suggest anything?
1628          */
1629         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1630                 tvb, offset, len, mask);
1631         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1632                 tvb, offset, len, mask);
1633         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1634                 tvb, offset, len, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1636                 tvb, offset, len, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1638                 tvb, offset, len, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1640                 tvb, offset, len, mask);
1641         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1642                 tvb, offset, len, mask);
1643         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1644                 tvb, offset, len, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1646                 tvb, offset, len, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1648                 tvb, offset, len, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1650                 tvb, offset, len, mask);
1651         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1652                 tvb, offset, len, mask);
1653         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1654                 tvb, offset, len, mask);
1655         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1656                 tvb, offset, len, mask);
1657         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1658                 tvb, offset, len, mask);
1659
1660         offset += len;
1661
1662         return offset;
1663 }
1664
1665 /* 3.11 */
1666 static int
1667 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1668 {
1669         guint32 mask;
1670
1671         mask = tvb_get_letohl(tvb, offset);
1672
1673         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1674
1675         return offset;
1676 }
1677
1678 static int
1679 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1680 {
1681         guint8 mask;
1682         proto_item *item = NULL;
1683         proto_tree *tree = NULL;
1684
1685         mask = tvb_get_guint8(tvb, offset);
1686
1687         if(parent_tree){
1688                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1689                         "File Attributes: 0x%02x", mask);
1690                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1691         }
1692         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1693                 tvb, offset, 1, mask);
1694         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1695                 tvb, offset, 1, mask);
1696         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1697                 tvb, offset, 1, mask);
1698         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1699                 tvb, offset, 1, mask);
1700         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1701                 tvb, offset, 1, mask);
1702         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1703                 tvb, offset, 1, mask);
1704
1705         offset += 1;
1706
1707         return offset;
1708 }
1709
1710 static const true_false_string tfs_search_attribute_read_only = {
1711         "Include READ ONLY files in search results",
1712         "Do NOT include read only files in search results",
1713 };
1714 static const true_false_string tfs_search_attribute_hidden = {
1715         "Include HIDDEN files in search results",
1716         "Do NOT include hidden files in search results"
1717 };
1718 static const true_false_string tfs_search_attribute_system = {
1719         "Include SYSTEM files in search results",
1720         "Do NOT include system files in search results"
1721 };
1722 static const true_false_string tfs_search_attribute_volume = {
1723         "Include VOLUME IDs in search results",
1724         "Do NOT include volume IDs in search results"
1725 };
1726 static const true_false_string tfs_search_attribute_directory = {
1727         "Include DIRECTORIES in search results",
1728         "Do NOT include directories in search results"
1729 };
1730 static const true_false_string tfs_search_attribute_archive = {
1731         "Include ARCHIVE files in search results",
1732         "Do NOT include archive files in search results"
1733 };
1734
1735 static int
1736 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1737 {
1738         guint16 mask;
1739         proto_item *item = NULL;
1740         proto_tree *tree = NULL;
1741
1742         mask = tvb_get_letohs(tvb, offset);
1743
1744         if(parent_tree){
1745                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1746                         "Search Attributes: 0x%04x", mask);
1747                 tree = proto_item_add_subtree(item, ett_smb_search);
1748         }
1749
1750         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1751                 tvb, offset, 2, mask);
1752         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1753                 tvb, offset, 2, mask);
1754         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1755                 tvb, offset, 2, mask);
1756         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1757                 tvb, offset, 2, mask);
1758         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1759                 tvb, offset, 2, mask);
1760         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1761                 tvb, offset, 2, mask);
1762
1763         offset += 2;
1764         return offset;
1765 }
1766
1767 #if 0
1768 /*
1769  * XXX - this isn't used.
1770  * Is this used for anything?  NT Create AndX doesn't use it.
1771  * Is there some 16-bit attribute field with more bits than Read Only,
1772  * Hidden, System, Volume ID, Directory, and Archive?
1773  */
1774 static int
1775 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1776 {
1777         guint32 mask;
1778         proto_item *item = NULL;
1779         proto_tree *tree = NULL;
1780
1781         mask = tvb_get_letohl(tvb, offset);
1782
1783         if(parent_tree){
1784                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1785                         "File Attributes: 0x%08x", mask);
1786                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1787         }
1788         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1789                 tvb, offset, 2, mask);
1790         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1791                 tvb, offset, 2, mask);
1792         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1793                 tvb, offset, 2, mask);
1794         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1795                 tvb, offset, 2, mask);
1796         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1797                 tvb, offset, 2, mask);
1798         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1799                 tvb, offset, 2, mask);
1800         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1801                 tvb, offset, 2, mask);
1802         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1803                 tvb, offset, 2, mask);
1804         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1805                 tvb, offset, 2, mask);
1806         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1807                 tvb, offset, 2, mask);
1808         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1809                 tvb, offset, 2, mask);
1810         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1811                 tvb, offset, 2, mask);
1812         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1813                 tvb, offset, 2, mask);
1814         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1815                 tvb, offset, 2, mask);
1816         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1817                 tvb, offset, 2, mask);
1818
1819         offset += 2;
1820
1821         return offset;
1822 }
1823 #endif
1824
1825
1826 #define SERVER_CAP_RAW_MODE            0x00000001
1827 #define SERVER_CAP_MPX_MODE            0x00000002
1828 #define SERVER_CAP_UNICODE             0x00000004
1829 #define SERVER_CAP_LARGE_FILES         0x00000008
1830 #define SERVER_CAP_NT_SMBS             0x00000010
1831 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1832 #define SERVER_CAP_STATUS32            0x00000040
1833 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1834 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1835 #define SERVER_CAP_NT_FIND             0x00000200
1836 #define SERVER_CAP_DFS                 0x00001000
1837 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1838 #define SERVER_CAP_LARGE_READX         0x00004000
1839 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1840 #define SERVER_CAP_UNIX                0x00800000
1841 #define SERVER_CAP_RESERVED            0x02000000
1842 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1843 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1844 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1845 static const true_false_string tfs_server_cap_raw_mode = {
1846         "Read Raw and Write Raw are supported",
1847         "Read Raw and Write Raw are not supported"
1848 };
1849 static const true_false_string tfs_server_cap_mpx_mode = {
1850         "Read Mpx and Write Mpx are supported",
1851         "Read Mpx and Write Mpx are not supported"
1852 };
1853 static const true_false_string tfs_server_cap_unicode = {
1854         "Unicode strings are supported",
1855         "Unicode strings are not supported"
1856 };
1857 static const true_false_string tfs_server_cap_large_files = {
1858         "Large files are supported",
1859         "Large files are not supported",
1860 };
1861 static const true_false_string tfs_server_cap_nt_smbs = {
1862         "NT SMBs are supported",
1863         "NT SMBs are not supported"
1864 };
1865 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1866         "RPC remote APIs are supported",
1867         "RPC remote APIs are not supported"
1868 };
1869 static const true_false_string tfs_server_cap_nt_status = {
1870         "NT status codes are supported",
1871         "NT status codes are not supported"
1872 };
1873 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1874         "Level 2 oplocks are supported",
1875         "Level 2 oplocks are not supported"
1876 };
1877 static const true_false_string tfs_server_cap_lock_and_read = {
1878         "Lock and Read is supported",
1879         "Lock and Read is not supported"
1880 };
1881 static const true_false_string tfs_server_cap_nt_find = {
1882         "NT Find is supported",
1883         "NT Find is not supported"
1884 };
1885 static const true_false_string tfs_server_cap_dfs = {
1886         "Dfs is supported",
1887         "Dfs is not supported"
1888 };
1889 static const true_false_string tfs_server_cap_infolevel_passthru = {
1890         "NT information level request passthrough is supported",
1891         "NT information level request passthrough is not supported"
1892 };
1893 static const true_false_string tfs_server_cap_large_readx = {
1894         "Large Read andX is supported",
1895         "Large Read andX is not supported"
1896 };
1897 static const true_false_string tfs_server_cap_large_writex = {
1898         "Large Write andX is supported",
1899         "Large Write andX is not supported"
1900 };
1901 static const true_false_string tfs_server_cap_unix = {
1902         "UNIX extensions are supported",
1903         "UNIX extensions are not supported"
1904 };
1905 static const true_false_string tfs_server_cap_reserved = {
1906         "Reserved",
1907         "Reserved"
1908 };
1909 static const true_false_string tfs_server_cap_bulk_transfer = {
1910         "Bulk Read and Bulk Write are supported",
1911         "Bulk Read and Bulk Write are not supported"
1912 };
1913 static const true_false_string tfs_server_cap_compressed_data = {
1914         "Compressed data transfer is supported",
1915         "Compressed data transfer is not supported"
1916 };
1917 static const true_false_string tfs_server_cap_extended_security = {
1918         "Extended security exchanges are supported",
1919         "Extended security exchanges are not supported"
1920 };
1921 static int
1922 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1923 {
1924         guint32 mask;
1925         proto_item *item = NULL;
1926         proto_tree *tree = NULL;
1927
1928         mask = tvb_get_letohl(tvb, offset);
1929
1930         if(parent_tree){
1931                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1932                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1933         }
1934
1935         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1936                 tvb, offset, 4, mask);
1937         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1938                 tvb, offset, 4, mask);
1939         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1940                 tvb, offset, 4, mask);
1941         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1942                 tvb, offset, 4, mask);
1943         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1944                 tvb, offset, 4, mask);
1945         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1946                 tvb, offset, 4, mask);
1947         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1948                 tvb, offset, 4, mask);
1949         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1950                 tvb, offset, 4, mask);
1951         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1952                 tvb, offset, 4, mask);
1953         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1954                 tvb, offset, 4, mask);
1955         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1956                 tvb, offset, 4, mask);
1957         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1958                 tvb, offset, 4, mask);
1959         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1960                 tvb, offset, 4, mask);
1961         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1962                 tvb, offset, 4, mask);
1963         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1964                 tvb, offset, 4, mask);
1965         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1966                 tvb, offset, 4, mask);
1967         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1968                 tvb, offset, 4, mask);
1969         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1970                 tvb, offset, 4, mask);
1971         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1972                 tvb, offset, 4, mask);
1973
1974         return mask;
1975 }
1976
1977 #define RAWMODE_READ   0x01
1978 #define RAWMODE_WRITE  0x02
1979 static const true_false_string tfs_rm_read = {
1980         "Read Raw is supported",
1981         "Read Raw is not supported"
1982 };
1983 static const true_false_string tfs_rm_write = {
1984         "Write Raw is supported",
1985         "Write Raw is not supported"
1986 };
1987
1988 static int
1989 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1990 {
1991         guint16 mask;
1992         proto_item *item = NULL;
1993         proto_tree *tree = NULL;
1994
1995         mask = tvb_get_letohs(tvb, offset);
1996
1997         if(parent_tree){
1998                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1999                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2000         }
2001
2002         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2003         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2004
2005         offset += 2;
2006
2007         return offset;
2008 }
2009
2010 #define SECURITY_MODE_MODE             0x01
2011 #define SECURITY_MODE_PASSWORD         0x02
2012 #define SECURITY_MODE_SIGNATURES       0x04
2013 #define SECURITY_MODE_SIG_REQUIRED     0x08
2014 static const true_false_string tfs_sm_mode = {
2015         "USER security mode",
2016         "SHARE security mode"
2017 };
2018 static const true_false_string tfs_sm_password = {
2019         "ENCRYPTED password. Use challenge/response",
2020         "PLAINTEXT password"
2021 };
2022 static const true_false_string tfs_sm_signatures = {
2023         "Security signatures ENABLED",
2024         "Security signatures NOT enabled"
2025 };
2026 static const true_false_string tfs_sm_sig_required = {
2027         "Security signatures REQUIRED",
2028         "Security signatures NOT required"
2029 };
2030
2031 static int
2032 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2033 {
2034         guint16 mask = 0;
2035         proto_item *item = NULL;
2036         proto_tree *tree = NULL;
2037
2038         switch(wc){
2039         case 13:
2040                 mask = tvb_get_letohs(tvb, offset);
2041                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2042                                 "Security Mode: 0x%04x", mask);
2043                 tree = proto_item_add_subtree(item, ett_smb_mode);
2044                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2045                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2046                 offset += 2;
2047                 break;
2048
2049         case 17:
2050                 mask = tvb_get_guint8(tvb, offset);
2051                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2052                                 "Security Mode: 0x%02x", mask);
2053                 tree = proto_item_add_subtree(item, ett_smb_mode);
2054                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2055                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2056                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2057                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2058                 offset += 1;
2059                 break;
2060         }
2061
2062         return offset;
2063 }
2064
2065 static int
2066 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2067 {
2068         proto_item *it = NULL;
2069         proto_tree *tr = NULL;
2070         guint16 bc;
2071         guint8 wc;
2072
2073         WORD_COUNT;
2074
2075         BYTE_COUNT;
2076
2077         if(tree){
2078                 tvb_ensure_bytes_exist(tvb, offset, bc);
2079                 it = proto_tree_add_text(tree, tvb, offset, bc,
2080                                 "Requested Dialects");
2081                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2082         }
2083
2084         while(bc){
2085                 int len;
2086                 const guint8 *str;
2087                 proto_item *dit = NULL;
2088                 proto_tree *dtr = NULL;
2089
2090                 /* XXX - what if this runs past bc? */
2091                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2092                 len = tvb_strsize(tvb, offset+1);
2093                 str = tvb_get_ptr(tvb, offset+1, len);
2094
2095                 if(tr){
2096                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2097                                         "Dialect: %s", str);
2098                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2099                 }
2100
2101                 /* Buffer Format */
2102                 CHECK_BYTE_COUNT(1);
2103                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2104                         TRUE);
2105                 COUNT_BYTES(1);
2106
2107                 /*Dialect Name */
2108                 CHECK_BYTE_COUNT(len);
2109                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2110                         len, str);
2111                 COUNT_BYTES(len);
2112         }
2113
2114         END_OF_SMB
2115
2116         return offset;
2117 }
2118
2119 static int
2120 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2121 {
2122         smb_info_t *si = pinfo->private_data;
2123         guint8 wc;
2124         guint16 dialect;
2125         const char *dn;
2126         int dn_len;
2127         guint16 bc;
2128         guint16 ekl=0;
2129         guint32 caps=0;
2130         gint16 tz;
2131
2132         DISSECTOR_ASSERT(si);
2133
2134         WORD_COUNT;
2135
2136         /* Dialect Index */
2137         dialect = tvb_get_letohs(tvb, offset);
2138         switch(wc){
2139         case 1:
2140                 if(dialect==0xffff){
2141                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2142                                 tvb, offset, 2, dialect,
2143                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2144                 } else {
2145                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2146                                 tvb, offset, 2, dialect);
2147                 }
2148                 break;
2149         case 13:
2150                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2151                         tvb, offset, 2, dialect,
2152                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2153                 break;
2154         case 17:
2155                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2156                         tvb, offset, 2, dialect,
2157                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2158                 break;
2159         default:
2160                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2161                 proto_tree_add_text(tree, tvb, offset, wc*2,
2162                         "Words for unknown response format");
2163                 offset += wc*2;
2164                 goto bytecount;
2165         }
2166         offset += 2;
2167
2168         switch(wc){
2169         case 13:
2170                 /* Security Mode */
2171                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2172
2173                 /* Maximum Transmit Buffer Size */
2174                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2175                         tvb, offset, 2, TRUE);
2176                 offset += 2;
2177
2178                 /* Maximum Multiplex Count */
2179                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2180                         tvb, offset, 2, TRUE);
2181                 offset += 2;
2182
2183                 /* Maximum Vcs Number */
2184                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2185                         tvb, offset, 2, TRUE);
2186                 offset += 2;
2187
2188                 /* raw mode */
2189                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2190
2191                 /* session key */
2192                 proto_tree_add_item(tree, hf_smb_session_key,
2193                         tvb, offset, 4, TRUE);
2194                 offset += 4;
2195
2196                 /* current time and date at server */
2197                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2198                     TRUE);
2199
2200                 /* time zone */
2201                 tz = tvb_get_letohs(tvb, offset);
2202                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2203                 offset += 2;
2204
2205                 /* encryption key length */
2206                 ekl = tvb_get_letohs(tvb, offset);
2207                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2208                 offset += 2;
2209
2210                 /* 2 reserved bytes */
2211                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2212                 offset += 2;
2213
2214                 break;
2215
2216         case 17:
2217                 /* Security Mode */
2218                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2219
2220                 /* Maximum Multiplex Count */
2221                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2222                         tvb, offset, 2, TRUE);
2223                 offset += 2;
2224
2225                 /* Maximum Vcs Number */
2226                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2227                         tvb, offset, 2, TRUE);
2228                 offset += 2;
2229
2230                 /* Maximum Transmit Buffer Size */
2231                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2232                         tvb, offset, 4, TRUE);
2233                 offset += 4;
2234
2235                 /* maximum raw buffer size */
2236                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2237                         tvb, offset, 4, TRUE);
2238                 offset += 4;
2239
2240                 /* session key */
2241                 proto_tree_add_item(tree, hf_smb_session_key,
2242                         tvb, offset, 4, TRUE);
2243                 offset += 4;
2244
2245                 /* server capabilities */
2246                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2247                 offset += 4;
2248
2249                 /* system time */
2250                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2251                                 hf_smb_system_time);
2252
2253                 /* time zone */
2254                 tz = tvb_get_letohs(tvb, offset);
2255                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2256                         tvb, offset, 2, tz,
2257                         "Server Time Zone: %d min from UTC", tz);
2258                 offset += 2;
2259
2260                 /* encryption key length */
2261                 ekl = tvb_get_guint8(tvb, offset);
2262                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2263                         tvb, offset, 1, ekl);
2264                 offset += 1;
2265
2266                 break;
2267         }
2268
2269         BYTE_COUNT;
2270
2271         switch(wc){
2272         case 13:
2273                 /* challenge/response encryption key */
2274                 if(ekl){
2275                         CHECK_BYTE_COUNT(ekl);
2276                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2277                         COUNT_BYTES(ekl);
2278                 }
2279
2280                 /*
2281                  * Primary domain.
2282                  *
2283                  * XXX - not present if negotiated dialect isn't
2284                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2285                  * have to see the request, or assume what dialect strings
2286                  * were sent, to determine that.
2287                  *
2288                  * Is this something other than a primary domain if the
2289                  * negotiated dialect is Windows for Workgroups 3.1a?
2290                  * It appears to be 8 bytes of binary data in at least
2291                  * one capture - is that an encryption key or something
2292                  * such as that?
2293                  */
2294                 dn = get_unicode_or_ascii_string(tvb, &offset,
2295                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2296                 if (dn == NULL)
2297                         goto endofcommand;
2298                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2299                         offset, dn_len,dn);
2300                 COUNT_BYTES(dn_len);
2301                 break;
2302
2303         case 17:
2304                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2305                         /* challenge/response encryption key */
2306                         /* XXX - is this aligned on an even boundary? */
2307                         if(ekl){
2308                                 CHECK_BYTE_COUNT(ekl);
2309                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2310                                         tvb, offset, ekl, TRUE);
2311                                 COUNT_BYTES(ekl);
2312                         }
2313
2314                         /* domain */
2315                         /* this string is special, unicode is flagged in caps */
2316                         /* This string is NOT padded to be 16bit aligned.
2317                            (seen in actual capture)
2318                            XXX - I've seen a capture where it appears to be
2319                            so aligned, but I've also seen captures where
2320                            it is.  The captures where it appeared to be
2321                            aligned may have been from buggy servers. */
2322                         /* However, don't get rid of existing setting */
2323                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2324                           si->unicode;
2325
2326                         dn = get_unicode_or_ascii_string(tvb,
2327                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2328                                 &bc);
2329                         if (dn == NULL)
2330                                 goto endofcommand;
2331                         proto_tree_add_string(tree, hf_smb_primary_domain,
2332                                 tvb, offset, dn_len, dn);
2333                         COUNT_BYTES(dn_len);
2334
2335                         /* server name, seen in w2k pro capture */
2336                         dn = get_unicode_or_ascii_string(tvb,
2337                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2338                                 &bc);
2339                         if (dn == NULL)
2340                                 goto endofcommand;
2341                         proto_tree_add_string(tree, hf_smb_server,
2342                                 tvb, offset, dn_len, dn);
2343                         COUNT_BYTES(dn_len);
2344
2345                 } else {
2346                         proto_item *blob_item;
2347                         guint16 sbloblen;
2348
2349                         /* guid */
2350                         /* XXX - show it in the standard Microsoft format
2351                            for GUIDs? */
2352                         CHECK_BYTE_COUNT(16);
2353                         proto_tree_add_item(tree, hf_smb_server_guid,
2354                                 tvb, offset, 16, TRUE);
2355                         COUNT_BYTES(16);
2356
2357                         /* security blob */
2358                         /* If it runs past the end of the captured data, don't
2359                          * try to put all of it into the protocol tree as the
2360                          * raw security blob; we might get an exception on 
2361                          * short frames and then we will not see anything at all
2362                          * of the security blob.
2363                          */
2364                         sbloblen=bc;
2365                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2366                                 sbloblen=tvb_length_remaining(tvb,offset);
2367                         }
2368                         blob_item = proto_tree_add_item(
2369                                 tree, hf_smb_security_blob,
2370                                 tvb, offset, sbloblen, TRUE);
2371
2372                         /* 
2373                          * If Extended security and BCC == 16, then raw 
2374                          * NTLMSSP is in use. We need to save this info
2375                          */
2376  
2377                         if(bc){
2378                                 tvbuff_t *gssapi_tvb;
2379                                 proto_tree *gssapi_tree;
2380
2381                                 gssapi_tree = proto_item_add_subtree(
2382                                         blob_item, ett_smb_secblob);
2383
2384                                 /*
2385                                  * Set the reported length of this to
2386                                  * the reported length of the blob,
2387                                  * rather than the amount of data
2388                                  * available from the blob, so that
2389                                  * we'll throw the right exception if
2390                                  * it's too short.
2391                                  */
2392                                 gssapi_tvb = tvb_new_subset(
2393                                         tvb, offset, sbloblen, bc);
2394
2395                                 call_dissector(
2396                                         gssapi_handle, gssapi_tvb, pinfo,
2397                                         gssapi_tree);
2398
2399                                 if (si->ct)
2400                                   si->ct->raw_ntlmssp = 0;
2401
2402                                 COUNT_BYTES(bc);
2403                         }
2404                         else { 
2405
2406                           /*
2407                            * There is no blob. We just have to make sure
2408                            * that subsequent routines know to call the 
2409                            * right things ...
2410                            */
2411
2412                           if (si->ct)
2413                             si->ct->raw_ntlmssp = 1;
2414
2415                         }
2416                 }
2417                 break;
2418         }
2419
2420         END_OF_SMB
2421
2422         return offset;
2423 }
2424
2425
2426 static int
2427 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2428 {
2429         smb_info_t *si = pinfo->private_data;
2430         int dn_len;
2431         const char *dn;
2432         guint8 wc;
2433         guint16 bc;
2434
2435         DISSECTOR_ASSERT(si);
2436
2437         WORD_COUNT;
2438
2439         BYTE_COUNT;
2440
2441         /* buffer format */
2442         CHECK_BYTE_COUNT(1);
2443         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2444         COUNT_BYTES(1);
2445
2446         /* dir name */
2447         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2448                 FALSE, FALSE, &bc);
2449
2450         if(si->sip){
2451                 si->sip->extra_info_type=SMB_EI_FILENAME;
2452                 si->sip->extra_info=se_strdup(dn);
2453         }
2454
2455         if (dn == NULL)
2456                 goto endofcommand;
2457         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2458                 dn);
2459         COUNT_BYTES(dn_len);
2460
2461         if (check_col(pinfo->cinfo, COL_INFO)) {
2462                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2463                     format_text(dn, strlen(dn)));
2464         }
2465
2466         END_OF_SMB
2467
2468         return offset;
2469 }
2470
2471 static int
2472 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2473 {
2474         guint8 wc;
2475         guint16 bc;
2476         smb_info_t *si = pinfo->private_data;
2477         proto_item *item=NULL;
2478
2479         DISSECTOR_ASSERT(si);
2480
2481         if(si->sip && si->sip->extra_info_type==SMB_EI_FILENAME){
2482                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, si->sip->extra_info);
2483                 PROTO_ITEM_SET_GENERATED(item);
2484         }
2485                 
2486
2487         WORD_COUNT;
2488
2489         BYTE_COUNT;
2490
2491         END_OF_SMB
2492
2493         return offset;
2494 }
2495
2496 static int
2497 dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2498 {
2499         guint8 wc;
2500         guint16 bc;
2501         smb_info_t *si = pinfo->private_data;
2502         proto_item *item=NULL;
2503
2504         DISSECTOR_ASSERT(si);
2505
2506         if(si->sip && si->sip->extra_info_type==SMB_EI_RENAMEDATA){
2507                 smb_rename_saved_info_t *rni=si->sip->extra_info;
2508
2509                 item=proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2510                 PROTO_ITEM_SET_GENERATED(item);
2511                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2512                 PROTO_ITEM_SET_GENERATED(item);
2513         }
2514                 
2515
2516         WORD_COUNT;
2517
2518         BYTE_COUNT;
2519
2520         END_OF_SMB
2521
2522         return offset;
2523 }
2524
2525 static int
2526 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2527 {
2528         guint16 ec, bc;
2529         guint8 wc;
2530
2531         WORD_COUNT;
2532
2533         /* echo count */
2534         ec = tvb_get_letohs(tvb, offset);
2535         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2536         offset += 2;
2537
2538         BYTE_COUNT;
2539
2540         if (bc != 0) {
2541                 /* echo data */
2542                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2543                 COUNT_BYTES(bc);
2544         }
2545
2546         END_OF_SMB
2547
2548         return offset;
2549 }
2550
2551 static int
2552 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2553 {
2554         guint16 bc;
2555         guint8 wc;
2556
2557         WORD_COUNT;
2558
2559         /* echo sequence number */
2560         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2561         offset += 2;
2562
2563         BYTE_COUNT;
2564
2565         if (bc != 0) {
2566                 /* echo data */
2567                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2568                 COUNT_BYTES(bc);
2569         }
2570
2571         END_OF_SMB
2572
2573         return offset;
2574 }
2575
2576 static int
2577 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2578 {
2579         smb_info_t *si = pinfo->private_data;
2580         int an_len, pwlen;
2581         const char *an;
2582         guint8 wc;
2583         guint16 bc;
2584
2585         DISSECTOR_ASSERT(si);
2586
2587         WORD_COUNT;
2588
2589         BYTE_COUNT;
2590
2591         /* buffer format */
2592         CHECK_BYTE_COUNT(1);
2593         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2594         COUNT_BYTES(1);
2595
2596         /* Path */
2597         an = get_unicode_or_ascii_string(tvb, &offset,
2598                 si->unicode, &an_len, FALSE, FALSE, &bc);
2599         if (an == NULL)
2600                 goto endofcommand;
2601         proto_tree_add_string(tree, hf_smb_path, tvb,
2602                 offset, an_len, an);
2603         COUNT_BYTES(an_len);
2604
2605         if (check_col(pinfo->cinfo, COL_INFO)) {
2606                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2607                     format_text(an, strlen(an)));
2608         }
2609
2610         /* buffer format */
2611         CHECK_BYTE_COUNT(1);
2612         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2613         COUNT_BYTES(1);
2614
2615         /* password, ANSI */
2616         /* XXX - what if this runs past bc? */
2617         pwlen = tvb_strsize(tvb, offset);
2618         CHECK_BYTE_COUNT(pwlen);
2619         proto_tree_add_item(tree, hf_smb_password,
2620                 tvb, offset, pwlen, TRUE);
2621         COUNT_BYTES(pwlen);
2622
2623         /* buffer format */
2624         CHECK_BYTE_COUNT(1);
2625         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2626         COUNT_BYTES(1);
2627
2628         /* Service */
2629         /*
2630          * XXX - the SNIA CIFS spec "Strings that are never passed in
2631          * Unicode are: ... The service name string in the
2632          * Tree_Connect_AndX SMB".  Is that claim false?
2633          */
2634         an = get_unicode_or_ascii_string(tvb, &offset,
2635                 si->unicode, &an_len, FALSE, FALSE, &bc);
2636         if (an == NULL)
2637                 goto endofcommand;
2638         proto_tree_add_string(tree, hf_smb_service, tvb,
2639                 offset, an_len, an);
2640         COUNT_BYTES(an_len);
2641
2642         END_OF_SMB
2643
2644         return offset;
2645 }
2646
2647 static int
2648 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2649 {
2650         proto_item *item, *subitem;
2651         proto_tree *tree;
2652         smb_uid_t *smb_uid=NULL;
2653
2654         item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2655         tree=proto_item_add_subtree(item, ett_smb_uid);
2656
2657         smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
2658         if(smb_uid){
2659                 if(smb_uid->domain && smb_uid->account)
2660                         proto_item_append_text(item, "  (");
2661                 if(smb_uid->domain){
2662                         proto_item_append_text(item, "%s", smb_uid->domain);
2663                         subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2664                         PROTO_ITEM_SET_GENERATED(subitem);
2665                 }
2666                 if(smb_uid->account){
2667                         proto_item_append_text(item, "\\%s", smb_uid->account);
2668                         subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2669                         PROTO_ITEM_SET_GENERATED(subitem);
2670                 }
2671                 if(smb_uid->domain && smb_uid->account)
2672                         proto_item_append_text(item, ")");
2673                 if(smb_uid->logged_in>0){
2674                         subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2675                         PROTO_ITEM_SET_GENERATED(subitem);
2676                 }
2677                 if(smb_uid->logged_out>0){
2678                         subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2679                         PROTO_ITEM_SET_GENERATED(subitem);
2680                 }
2681         }
2682         offset += 2;
2683
2684         return offset;
2685 }
2686
2687 static int
2688 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
2689 {
2690         smb_info_t *si = pinfo->private_data;
2691         proto_item *it;
2692         proto_tree *tr;
2693         smb_tid_info_t *tid_info=NULL;
2694
2695         DISSECTOR_ASSERT(si);
2696
2697         /* tid */
2698         it=proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2699         tr=proto_item_add_subtree(it, ett_smb_tid);
2700         offset += 2;
2701
2702         if((!pinfo->fd->flags.visited) && is_created){
2703                 tid_info=se_alloc(sizeof(smb_tid_info_t));
2704                 tid_info->opened_in=pinfo->fd->num;
2705                 tid_info->closed_in=0;
2706                 tid_info->type=SMB_FID_TYPE_UNKNOWN;
2707                 if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
2708                         tid_info->filename=si->sip->extra_info;
2709                 } else {
2710                         tid_info->filename=NULL;
2711                 }
2712                 se_tree_insert32(si->ct->tid_tree, tid, tid_info);
2713         }
2714
2715         if(!tid_info){
2716                 tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
2717         }
2718         if(!tid_info){
2719                 return offset;
2720         }
2721
2722         if((!pinfo->fd->flags.visited) && is_closed){
2723                 tid_info->closed_in=pinfo->fd->num;
2724         }
2725
2726         if(tid_info->opened_in){
2727                 if(tid_info->filename){
2728                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2729
2730                         it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2731                         PROTO_ITEM_SET_GENERATED(it);
2732                 }
2733
2734                 it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2735                 PROTO_ITEM_SET_GENERATED(it);
2736         }               
2737         if(tid_info->closed_in){
2738                 it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2739                 PROTO_ITEM_SET_GENERATED(it);
2740         }               
2741
2742
2743         return offset;
2744 }
2745
2746 static int
2747 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2748 {
2749         guint8 wc;
2750         guint16 bc;
2751
2752         WORD_COUNT;
2753
2754         /* Maximum Buffer Size */
2755         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2756         offset += 2;
2757
2758         /* tid */
2759         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE);
2760
2761         BYTE_COUNT;
2762
2763         END_OF_SMB
2764
2765         return offset;
2766 }
2767
2768
2769 static const true_false_string tfs_of_create = {
2770         "Create file if it does not exist",
2771         "Fail if file does not exist"
2772 };
2773 static const value_string of_open[] = {
2774         { 0,            "Fail if file exists"},
2775         { 1,            "Open file if it exists"},
2776         { 2,            "Truncate file if it exists"},
2777         {0, NULL}
2778 };
2779 static int
2780 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2781 {
2782         guint16 mask;
2783         proto_item *item = NULL;
2784         proto_tree *tree = NULL;
2785
2786         mask = tvb_get_letohs(tvb, offset);
2787
2788         if(parent_tree){
2789                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2790                         "Open Function: 0x%04x", mask);
2791                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2792         }
2793
2794         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2795                 tvb, offset, 2, mask);
2796         proto_tree_add_uint(tree, hf_smb_open_function_open,
2797                 tvb, offset, 2, mask);
2798
2799         offset += 2;
2800
2801         return offset;
2802 }
2803
2804
2805 static const true_false_string tfs_mf_file = {
2806         "Target must be a file",
2807         "Target needn't be a file"
2808 };
2809 static const true_false_string tfs_mf_dir = {
2810         "Target must be a directory",
2811         "Target needn't be a directory"
2812 };
2813 static const true_false_string tfs_mf_verify = {
2814         "MUST verify all writes",
2815         "Don't have to verify writes"
2816 };
2817 static int
2818 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2819 {
2820         guint16 mask;
2821         proto_item *item = NULL;
2822         proto_tree *tree = NULL;
2823
2824         mask = tvb_get_letohs(tvb, offset);
2825
2826         if(parent_tree){
2827                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2828                         "Flags: 0x%04x", mask);
2829                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2830         }
2831
2832         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2833                 tvb, offset, 2, mask);
2834         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2835                 tvb, offset, 2, mask);
2836         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2837                 tvb, offset, 2, mask);
2838
2839         offset += 2;
2840
2841         return offset;
2842 }
2843
2844 static const true_false_string tfs_cf_mode = {
2845         "ASCII",
2846         "Binary"
2847 };
2848 static const true_false_string tfs_cf_tree_copy = {
2849         "Copy is a tree copy",
2850         "Copy is a file copy"
2851 };
2852 static const true_false_string tfs_cf_ea_action = {
2853         "Fail copy",
2854         "Discard EAs"
2855 };
2856 static int
2857 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2858 {
2859         guint16 mask;
2860         proto_item *item = NULL;
2861         proto_tree *tree = NULL;
2862
2863         mask = tvb_get_letohs(tvb, offset);
2864
2865         if(parent_tree){
2866                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2867                         "Flags: 0x%04x", mask);
2868                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2869         }
2870
2871         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2872                 tvb, offset, 2, mask);
2873         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2874                 tvb, offset, 2, mask);
2875         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2876                 tvb, offset, 2, mask);
2877         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2878                 tvb, offset, 2, mask);
2879         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2880                 tvb, offset, 2, mask);
2881         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2882                 tvb, offset, 2, mask);
2883         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2884                 tvb, offset, 2, mask);
2885
2886         offset += 2;
2887
2888         return offset;
2889 }
2890
2891 static int
2892 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2893 {
2894         smb_info_t *si = pinfo->private_data;
2895         int fn_len;
2896         guint16 tid;
2897         guint16 bc;
2898         guint8 wc;
2899         const char *fn;
2900
2901         DISSECTOR_ASSERT(si);
2902
2903         WORD_COUNT;
2904
2905         /* tid */
2906         tid = tvb_get_letohs(tvb, offset);
2907         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2908
2909         /* open function */
2910         offset = dissect_open_function(tvb, tree, offset);
2911
2912         /* move flags */
2913         offset = dissect_move_flags(tvb, tree, offset);
2914
2915         BYTE_COUNT;
2916
2917         /* buffer format */
2918         CHECK_BYTE_COUNT(1);
2919         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2920         COUNT_BYTES(1);
2921
2922         /* file name */
2923         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2924                 FALSE, FALSE, &bc);
2925         if (fn == NULL)
2926                 goto endofcommand;
2927         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2928                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
2929         COUNT_BYTES(fn_len);
2930
2931         if (check_col(pinfo->cinfo, COL_INFO)) {
2932                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
2933                     format_text(fn, strlen(fn)));
2934         }
2935
2936         /* buffer format */
2937         CHECK_BYTE_COUNT(1);
2938         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2939         COUNT_BYTES(1);
2940
2941         /* file name */
2942         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2943                 FALSE, FALSE, &bc);
2944         if (fn == NULL)
2945                 goto endofcommand;
2946         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2947                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
2948         COUNT_BYTES(fn_len);
2949
2950         if (check_col(pinfo->cinfo, COL_INFO)) {
2951                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
2952                     format_text(fn, strlen(fn)));
2953         }
2954
2955         END_OF_SMB
2956
2957         return offset;
2958 }
2959
2960 static int
2961 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2962 {
2963         smb_info_t *si = pinfo->private_data;
2964         int fn_len;
2965         guint16 tid;
2966         guint16 bc;
2967         guint8 wc;
2968         const char *fn;
2969
2970         DISSECTOR_ASSERT(si);
2971
2972         WORD_COUNT;
2973
2974         /* tid */
2975         tid = tvb_get_letohs(tvb, offset);
2976         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2977
2978         /* open function */
2979         offset = dissect_open_function(tvb, tree, offset);
2980
2981         /* copy flags */
2982         offset = dissect_copy_flags(tvb, tree, offset);
2983
2984         BYTE_COUNT;
2985
2986         /* buffer format */
2987         CHECK_BYTE_COUNT(1);
2988         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2989         COUNT_BYTES(1);
2990
2991         /* file name */
2992         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2993                 FALSE, FALSE, &bc);
2994         if (fn == NULL)
2995                 goto endofcommand;
2996         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2997                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
2998         COUNT_BYTES(fn_len);
2999
3000         if (check_col(pinfo->cinfo, COL_INFO)) {
3001                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3002                     format_text(fn, strlen(fn)));
3003         }
3004
3005         /* buffer format */
3006         CHECK_BYTE_COUNT(1);
3007         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3008         COUNT_BYTES(1);
3009
3010         /* file name */
3011         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3012                 FALSE, FALSE, &bc);
3013         if (fn == NULL)
3014                 goto endofcommand;
3015         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3016                 fn_len, fn, "Destination File Name: %s",
3017                 format_text(fn, strlen(fn)));
3018         COUNT_BYTES(fn_len);
3019
3020         if (check_col(pinfo->cinfo, COL_INFO)) {
3021                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3022         }
3023
3024         END_OF_SMB
3025
3026         return offset;
3027 }
3028
3029 static int
3030 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3031 {
3032         smb_info_t *si = pinfo->private_data;
3033         int fn_len;
3034         const char *fn;
3035         guint8 wc;
3036         guint16 bc;
3037
3038         DISSECTOR_ASSERT(si);
3039
3040         WORD_COUNT;
3041
3042         /* # of files moved */
3043         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
3044         offset += 2;
3045
3046         BYTE_COUNT;
3047
3048         /* buffer format */
3049         CHECK_BYTE_COUNT(1);
3050         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3051         COUNT_BYTES(1);
3052
3053         /* file name */
3054         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3055                 FALSE, FALSE, &bc);
3056         if (fn == NULL)
3057                 goto endofcommand;
3058         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3059                 fn);
3060         COUNT_BYTES(fn_len);
3061
3062         END_OF_SMB
3063
3064         return offset;
3065 }
3066
3067 static int
3068 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3069 {
3070         smb_info_t *si = pinfo->private_data;
3071         int fn_len;
3072         const char *fn;
3073         guint8 wc;
3074         guint16 bc;
3075
3076         DISSECTOR_ASSERT(si);
3077
3078         WORD_COUNT;
3079
3080         /* desired access */
3081         offset = dissect_access(tvb, tree, offset, "Desired");
3082
3083         /* Search Attributes */
3084         offset = dissect_search_attributes(tvb, tree, offset);
3085
3086         BYTE_COUNT;
3087
3088         /* buffer format */
3089         CHECK_BYTE_COUNT(1);
3090         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3091         COUNT_BYTES(1);
3092
3093         /* file name */
3094         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3095                 FALSE, FALSE, &bc);
3096         if (fn == NULL)
3097                 goto endofcommand;
3098         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3099                 fn);
3100         COUNT_BYTES(fn_len);
3101
3102         if (check_col(pinfo->cinfo, COL_INFO)) {
3103                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3104                     format_text(fn, strlen(fn)));
3105         }
3106
3107         END_OF_SMB
3108
3109         return offset;
3110 }
3111
3112
3113
3114 static int
3115 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3116     int len, guint32 mask)
3117 {
3118         proto_item *item = NULL;
3119         proto_tree *tree = NULL;
3120
3121         if(parent_tree){
3122                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3123
3124                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3125         }
3126
3127         /*
3128          * XXX - it's 0x00000016 in at least one capture, but
3129          * Network Monitor doesn't say what the 0x00000010 bit is.
3130          * Does the Win32 API documentation, or NT Native API book,
3131          * suggest anything?
3132          *
3133          * That is the extended response desired bit ... RJS, from Samba
3134          * Well, maybe. Samba thinks it is, and uses it to encode
3135          * OpLock granted as the high order bit of the Action field
3136          * in the response. However, Windows does not do that. Or at least
3137          * Win2K doesn't.
3138          */
3139         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3140                                tvb, offset, len, mask);
3141         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3142                 tvb, offset, len, mask);
3143         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3144                 tvb, offset, len, mask);
3145         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3146                 tvb, offset, len, mask);
3147
3148         offset += len;
3149
3150         return offset;
3151 }
3152
3153 /* FIXME: need to call dissect_nt_access_mask() instead */
3154 static int
3155 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3156     int offset, int len, guint32 mask)
3157 {
3158         proto_item *item = NULL;
3159         proto_tree *tree = NULL;
3160
3161         if(parent_tree){
3162                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3163                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3164         }
3165
3166         /*
3167          * Some of these bits come from
3168          *
3169          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3170          *
3171          * and others come from the section on ZwOpenFile in "Windows(R)
3172          * NT(R)/2000 Native API Reference".
3173          */
3174         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3175                 tvb, offset, len, mask);
3176         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3177                 tvb, offset, len, mask);
3178         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3179                 tvb, offset, len, mask);
3180         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3181                 tvb, offset, len, mask);
3182         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3183                 tvb, offset, len, mask);
3184         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3185                 tvb, offset, len, mask);
3186         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3187                 tvb, offset, len, mask);
3188         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3189                 tvb, offset, len, mask);
3190         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3191                 tvb, offset, len, mask);
3192         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3193                 tvb, offset, len, mask);
3194         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3195                 tvb, offset, len, mask);
3196         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3197                 tvb, offset, len, mask);
3198         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3199                 tvb, offset, len, mask);
3200         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3201                 tvb, offset, len, mask);
3202         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3203                 tvb, offset, len, mask);
3204         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3205                 tvb, offset, len, mask);
3206         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3207                 tvb, offset, len, mask);
3208         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3209                 tvb, offset, len, mask);
3210         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3211                 tvb, offset, len, mask);
3212         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3213                 tvb, offset, len, mask);
3214
3215         offset += len;
3216
3217         return offset;
3218 }
3219
3220 int
3221 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3222 {
3223         guint32 mask;
3224
3225         mask = tvb_get_letohl(tvb, offset);
3226
3227         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3228
3229         return offset;
3230 }
3231
3232
3233 #define SHARE_ACCESS_DELETE     0x00000004
3234 #define SHARE_ACCESS_WRITE      0x00000002
3235 #define SHARE_ACCESS_READ       0x00000001
3236
3237 static int
3238 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3239     int offset, int len, guint32 mask)
3240 {
3241         proto_item *item = NULL;
3242         proto_tree *tree = NULL;
3243
3244         if(parent_tree){
3245                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3246                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3247         }
3248
3249         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3250                 tvb, offset, len, mask);
3251         if(mask&SHARE_ACCESS_DELETE){
3252                 proto_item_append_text(item, " SHARE_DELETE");
3253         }
3254
3255         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3256                 tvb, offset, len, mask);
3257         if(mask&SHARE_ACCESS_WRITE){
3258                 proto_item_append_text(item, " SHARE_WRITE");
3259         }
3260
3261         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3262                 tvb, offset, len, mask);
3263         if(mask&SHARE_ACCESS_READ){
3264                 proto_item_append_text(item, " SHARE_READ");
3265         }
3266
3267         offset += len;
3268
3269         return offset;
3270 }
3271
3272 int
3273 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3274 {
3275         guint32 mask;
3276
3277         mask = tvb_get_letohl(tvb, offset);
3278
3279         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3280
3281         return offset;
3282 }
3283
3284
3285 static int
3286 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3287     int offset, int len, guint32 mask)
3288 {
3289         proto_item *item = NULL;
3290         proto_tree *tree = NULL;
3291
3292         if(parent_tree){
3293                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3294                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3295         }
3296
3297         /*
3298          * From
3299          *
3300          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3301          */
3302         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3303                 tvb, offset, len, mask);
3304         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3305                 tvb, offset, len, mask);
3306         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3307                 tvb, offset, len, mask);
3308         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3309                 tvb, offset, len, mask);
3310         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3311                 tvb, offset, len, mask);
3312         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3313                 tvb, offset, len, mask);
3314         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3315                 tvb, offset, len, mask);
3316         proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3317                 tvb, offset, len, mask);
3318         proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3319                 tvb, offset, len, mask);
3320         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3321                 tvb, offset, len, mask);
3322         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3323                 tvb, offset, len, mask);
3324         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3325                 tvb, offset, len, mask);
3326         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3327                 tvb, offset, len, mask);
3328         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3329                 tvb, offset, len, mask);
3330         proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3331                 tvb, offset, len, mask);
3332         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3333                 tvb, offset, len, mask);
3334         proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3335                 tvb, offset, len, mask);
3336         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3337                 tvb, offset, len, mask);
3338         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3339                 tvb, offset, len, mask);
3340         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3341                 tvb, offset, len, mask);
3342
3343         offset += len;
3344
3345         return offset;
3346 }
3347
3348 int
3349 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3350 {
3351         guint32 mask;
3352
3353         mask = tvb_get_letohl(tvb, offset);
3354
3355         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3356
3357         return offset;
3358 }
3359
3360
3361 /* fids are scoped by tcp session */
3362 smb_fid_info_t *
3363 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3364     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
3365 {
3366         smb_info_t *si = pinfo->private_data;
3367         smb_saved_info_t *sip = si->sip;
3368         proto_item *it;
3369         proto_tree *tr;
3370         smb_fid_info_t *fid_info=NULL;
3371
3372         DISSECTOR_ASSERT(si);
3373
3374         it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3375         if(is_generated){
3376                 PROTO_ITEM_SET_GENERATED(it);
3377         }
3378         tr=proto_item_add_subtree(it, ett_smb_fid);
3379         if (check_col(pinfo->cinfo, COL_INFO))
3380                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3381
3382         if((!pinfo->fd->flags.visited) && is_created){
3383                 fid_info=se_alloc(sizeof(smb_fid_info_t));
3384                 fid_info->opened_in=pinfo->fd->num;
3385                 fid_info->closed_in=0;
3386                 fid_info->type=SMB_FID_TYPE_UNKNOWN;
3387                 if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
3388                         fid_info->fsi=si->sip->extra_info;
3389                 } else {
3390                         fid_info->fsi=NULL;
3391                 }
3392
3393                 se_tree_insert32(si->ct->fid_tree, fid, fid_info);
3394         }
3395
3396         if(!fid_info){
3397                 fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
3398         }
3399         if(!fid_info){
3400                 return NULL;
3401         }
3402
3403         /* Store the fid in the transaction structure and remember if
3404            it was in the request or in the reply we saw it 
3405          */
3406         if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3407                 sip->fid=fid;
3408                 if(si->request){
3409                         sip->fid_seen_in_request=TRUE;
3410                 } else {
3411                         sip->fid_seen_in_request=FALSE;
3412                 }
3413         }
3414
3415         if((!pinfo->fd->flags.visited) && is_closed){
3416                 fid_info->closed_in=pinfo->fd->num;
3417         }
3418
3419         if(fid_info->opened_in){
3420                 it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3421                 PROTO_ITEM_SET_GENERATED(it);
3422         }
3423
3424         if(fid_info->closed_in){
3425                 it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3426                 PROTO_ITEM_SET_GENERATED(it);
3427         }
3428                 
3429
3430         if(fid_info->opened_in){
3431                 if(fid_info->fsi && fid_info->fsi->filename){
3432                         it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3433                         PROTO_ITEM_SET_GENERATED(it);
3434                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3435                         dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3436                         dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3437                         dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3438                         dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3439                         dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3440                         it=proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3441                         PROTO_ITEM_SET_GENERATED(it);
3442                 }
3443         }               
3444
3445         return fid_info;
3446 }
3447
3448 static int
3449 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3450 {
3451         guint8 wc;
3452         guint16 bc;
3453         guint16 fid;
3454
3455         WORD_COUNT;
3456
3457         /* fid */
3458         fid = tvb_get_letohs(tvb, offset);
3459         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3460         offset += 2;
3461
3462         /* File Attributes */
3463         offset = dissect_file_attributes(tvb, tree, offset, 2);
3464
3465         /* last write time */
3466         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3467
3468         /* File Size */
3469         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3470         offset += 4;
3471
3472         /* granted access */
3473         offset = dissect_access(tvb, tree, offset, "Granted");
3474
3475         BYTE_COUNT;
3476
3477         END_OF_SMB
3478
3479         return offset;
3480 }
3481
3482 static int
3483 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3484 {
3485         guint8 wc;
3486         guint16 bc;
3487         guint16 fid;
3488
3489         WORD_COUNT;
3490
3491         /* fid */
3492         fid = tvb_get_letohs(tvb, offset);
3493         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3494         offset += 2;
3495
3496         BYTE_COUNT;
3497
3498         END_OF_SMB
3499
3500         return offset;
3501 }
3502
3503 static int
3504 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3505 {
3506         guint8 wc;
3507         guint16 bc;
3508         guint16 fid;
3509
3510         WORD_COUNT;
3511
3512         /* fid */
3513         fid = tvb_get_letohs(tvb, offset);
3514         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3515         offset += 2;
3516
3517         BYTE_COUNT;
3518
3519         END_OF_SMB
3520
3521         return offset;
3522 }
3523
3524 static int
3525 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3526 {
3527         guint8 wc;
3528         guint16 bc;
3529         guint16 fid;
3530
3531         WORD_COUNT;
3532
3533         /* fid */
3534         fid = tvb_get_letohs(tvb, offset);
3535         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3536         offset += 2;
3537
3538         BYTE_COUNT;
3539
3540         END_OF_SMB
3541
3542         return offset;
3543 }
3544
3545 static int
3546 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3547 {
3548         guint8 wc;
3549         guint16 bc;
3550         guint16 fid;
3551
3552         WORD_COUNT;
3553
3554         /* fid */
3555         fid = tvb_get_letohs(tvb, offset);
3556         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3557         offset += 2;
3558
3559         BYTE_COUNT;
3560
3561         END_OF_SMB
3562
3563         return offset;
3564 }
3565
3566 static int
3567 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3568 {
3569         guint8 wc;
3570         guint16 bc;
3571         guint16 fid;
3572
3573         WORD_COUNT;
3574
3575         /* fid */
3576         fid = tvb_get_letohs(tvb, offset);
3577         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3578         offset += 2;
3579
3580         BYTE_COUNT;
3581
3582         END_OF_SMB
3583
3584         return offset;
3585 }
3586
3587 static int
3588 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3589 {
3590         guint8 wc;
3591         guint16 bc;
3592         guint16 fid;
3593
3594         WORD_COUNT;
3595
3596         /* fid */
3597         fid = tvb_get_letohs(tvb, offset);
3598         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3599         offset += 2;
3600
3601         BYTE_COUNT;
3602
3603         END_OF_SMB
3604
3605         return offset;
3606 }
3607
3608 static int
3609 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3610 {
3611         smb_info_t *si = pinfo->private_data;
3612         int fn_len;
3613         const char *fn;
3614         guint8 wc;
3615         guint16 bc;
3616
3617         DISSECTOR_ASSERT(si);
3618
3619         WORD_COUNT;
3620
3621         /* file attributes */
3622         offset = dissect_file_attributes(tvb, tree, offset, 2);
3623
3624         /* creation time */
3625         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3626
3627         BYTE_COUNT;
3628
3629         /* buffer format */
3630         CHECK_BYTE_COUNT(1);
3631         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3632         COUNT_BYTES(1);
3633
3634         /* File Name */
3635         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3636                 FALSE, FALSE, &bc);
3637         if (fn == NULL)
3638                 goto endofcommand;
3639         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3640                 fn);
3641         COUNT_BYTES(fn_len);
3642
3643         if (check_col(pinfo->cinfo, COL_INFO)) {
3644                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3645                     format_text(fn, strlen(fn)));
3646         }
3647
3648         END_OF_SMB
3649
3650         return offset;
3651 }
3652
3653 static int
3654 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3655 {
3656         guint8 wc;
3657         guint16 bc, fid;
3658
3659         WORD_COUNT;
3660
3661         /* fid */
3662         fid = tvb_get_letohs(tvb, offset);
3663         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3664         offset += 2;
3665
3666         /* last write time */
3667         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3668
3669         BYTE_COUNT;
3670
3671         END_OF_SMB
3672
3673         return offset;
3674 }
3675
3676 static int
3677 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3678 {
3679         smb_info_t *si = pinfo->private_data;
3680         int fn_len;
3681         const char *fn;
3682         guint8 wc;
3683         guint16 bc;
3684
3685         DISSECTOR_ASSERT(si);
3686
3687         WORD_COUNT;
3688
3689         /* search attributes */
3690         offset = dissect_search_attributes(tvb, tree, offset);
3691
3692         BYTE_COUNT;
3693
3694         /* buffer format */
3695         CHECK_BYTE_COUNT(1);
3696         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3697         COUNT_BYTES(1);
3698
3699         /* file name */
3700         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3701                 FALSE, FALSE, &bc);
3702
3703         if(si->sip){
3704                 si->sip->extra_info_type=SMB_EI_FILENAME;
3705                 si->sip->extra_info=se_strdup(fn);
3706         }
3707
3708         if (fn == NULL)
3709                 goto endofcommand;
3710         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3711                 fn);
3712         COUNT_BYTES(fn_len);
3713
3714         if (check_col(pinfo->cinfo, COL_INFO)) {
3715                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3716                     format_text(fn, strlen(fn)));
3717         }
3718
3719         END_OF_SMB
3720
3721         return offset;
3722 }
3723
3724 static int
3725 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3726 {
3727         smb_info_t *si = pinfo->private_data;
3728         int fn_len;
3729         const char *fn, *old_name=NULL, *new_name=NULL;
3730         guint8 wc;
3731         guint16 bc;
3732         smb_rename_saved_info_t *rni=NULL;
3733
3734         DISSECTOR_ASSERT(si);
3735
3736         WORD_COUNT;
3737
3738         /* search attributes */
3739         offset = dissect_search_attributes(tvb, tree, offset);
3740
3741         BYTE_COUNT;
3742
3743         /* buffer format */
3744         CHECK_BYTE_COUNT(1);
3745         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3746         COUNT_BYTES(1);
3747
3748         /* old file name */
3749         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3750                 FALSE, FALSE, &bc);
3751         if (fn == NULL)
3752                 goto endofcommand;
3753         old_name=fn;
3754         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3755                 fn);
3756         COUNT_BYTES(fn_len);
3757
3758         if (check_col(pinfo->cinfo, COL_INFO)) {
3759                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3760                     format_text(fn, strlen(fn)));
3761         }
3762
3763         /* buffer format */
3764         CHECK_BYTE_COUNT(1);
3765         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3766         COUNT_BYTES(1);
3767
3768         /* file name */
3769         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3770                 FALSE, FALSE, &bc);
3771         if (fn == NULL)
3772                 goto endofcommand;
3773         new_name=fn;
3774         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3775                 fn);
3776         COUNT_BYTES(fn_len);
3777
3778         if (check_col(pinfo->cinfo, COL_INFO)) {
3779                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3780                     format_text(fn, strlen(fn)));
3781         }
3782
3783         END_OF_SMB
3784
3785         /* save the offset/len for this transaction */
3786         if(si->sip && !pinfo->fd->flags.visited){
3787                 rni=se_alloc(sizeof(smb_rename_saved_info_t));
3788                 rni->old_name=se_strdup(old_name);
3789                 rni->new_name=se_strdup(new_name);
3790
3791                 si->sip->extra_info_type=SMB_EI_RENAMEDATA;
3792                 si->sip->extra_info=rni;
3793         }
3794
3795         return offset;
3796 }
3797
3798 static int
3799 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3800 {
3801         smb_info_t *si = pinfo->private_data;
3802         int fn_len;
3803         const char *fn;
3804         guint8 wc;
3805         guint16 bc;
3806
3807         DISSECTOR_ASSERT(si);
3808
3809         WORD_COUNT;
3810
3811         /* search attributes */
3812         offset = dissect_search_attributes(tvb, tree, offset);
3813
3814         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3815         offset += 2;
3816
3817         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3818         offset += 4;
3819
3820         BYTE_COUNT;
3821
3822         /* buffer format */
3823         CHECK_BYTE_COUNT(1);
3824         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3825         COUNT_BYTES(1);
3826
3827         /* old file name */
3828         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3829                 FALSE, FALSE, &bc);
3830         if (fn == NULL)
3831                 goto endofcommand;
3832         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3833                 fn);
3834         COUNT_BYTES(fn_len);
3835
3836         if (check_col(pinfo->cinfo, COL_INFO)) {
3837                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3838                     format_text(fn, strlen(fn)));
3839         }
3840
3841         /* buffer format */
3842         CHECK_BYTE_COUNT(1);
3843         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3844         COUNT_BYTES(1);
3845
3846         /* file name */
3847         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3848                 FALSE, FALSE, &bc);
3849         if (fn == NULL)
3850                 goto endofcommand;
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         return offset;
3863 }
3864
3865
3866 static int
3867 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3868 {
3869         smb_info_t *si = pinfo->private_data;
3870         guint16 bc;
3871         guint8 wc;
3872         const char *fn;
3873         int fn_len;
3874
3875         DISSECTOR_ASSERT(si);
3876
3877         WORD_COUNT;
3878
3879         BYTE_COUNT;
3880
3881         /* Buffer Format */
3882         CHECK_BYTE_COUNT(1);
3883         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3884         COUNT_BYTES(1);
3885
3886         /* File Name */
3887         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3888                 FALSE, FALSE, &bc);
3889         if (fn == NULL)
3890                 goto endofcommand;
3891         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3892                 fn);
3893         COUNT_BYTES(fn_len);
3894
3895         if (check_col(pinfo->cinfo, COL_INFO)) {
3896                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3897                     format_text(fn, strlen(fn)));
3898         }
3899
3900         END_OF_SMB
3901
3902         return offset;
3903 }
3904
3905 static int
3906 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3907 {
3908         guint16 bc;
3909         guint8 wc;
3910
3911         WORD_COUNT;
3912
3913         /* File Attributes */
3914         offset = dissect_file_attributes(tvb, tree, offset, 2);
3915
3916         /* Last Write Time */
3917         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3918
3919         /* File Size */
3920         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3921         offset += 4;
3922
3923         /* 10 reserved bytes */
3924         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3925         offset += 10;
3926
3927         BYTE_COUNT;
3928
3929         END_OF_SMB
3930
3931         return offset;
3932 }
3933
3934 static int
3935 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3936 {
3937         smb_info_t *si = pinfo->private_data;
3938         int fn_len;
3939         const char *fn;
3940         guint8 wc;
3941         guint16 bc;
3942
3943         DISSECTOR_ASSERT(si);
3944
3945         WORD_COUNT;
3946
3947         /* file attributes */
3948         offset = dissect_file_attributes(tvb, tree, offset, 2);
3949
3950         /* last write time */
3951         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3952
3953         /* 10 reserved bytes */
3954         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3955         offset += 10;
3956
3957         BYTE_COUNT;
3958
3959         /* buffer format */
3960         CHECK_BYTE_COUNT(1);
3961         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3962         COUNT_BYTES(1);
3963
3964         /* file name */
3965         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3966                 FALSE, FALSE, &bc);
3967         if (fn == NULL)
3968                 goto endofcommand;
3969         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3970                 fn);
3971         COUNT_BYTES(fn_len);
3972
3973         if (check_col(pinfo->cinfo, COL_INFO)) {
3974                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3975                     format_text(fn, strlen(fn)));
3976         }
3977
3978         END_OF_SMB
3979
3980         return offset;
3981 }
3982
3983 static int
3984 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3985 {
3986         guint8 wc;
3987         guint16 cnt=0, bc;
3988         guint32 ofs=0;
3989         unsigned int fid;
3990
3991         WORD_COUNT;
3992
3993         /* fid */
3994         fid = tvb_get_letohs(tvb, offset);
3995         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
3996         offset += 2;
3997
3998         /* read count */
3999         cnt = tvb_get_letohs(tvb, offset);
4000         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4001         offset += 2;
4002
4003         /* offset */
4004         ofs = tvb_get_letohl(tvb, offset);
4005         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4006         offset += 4;
4007
4008         if (check_col(pinfo->cinfo, COL_INFO))
4009                 col_append_fstr(pinfo->cinfo, COL_INFO,
4010                                 ", %u byte%s at offset %u", cnt,
4011                                 (cnt == 1) ? "" : "s", ofs);
4012
4013         /* remaining */
4014         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4015         offset += 2;
4016
4017         BYTE_COUNT;
4018
4019         END_OF_SMB
4020
4021         return offset;
4022 }
4023
4024 int
4025 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4026 {
4027         int tvblen;
4028
4029         if(bc>datalen){
4030                 /* We have some initial padding bytes. */
4031                 /* XXX - use the data offset here instead? */
4032                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4033                         TRUE);
4034                 offset += bc-datalen;
4035                 bc = datalen;
4036         }
4037         tvblen = tvb_length_remaining(tvb, offset);
4038         if(bc>tvblen){
4039                 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);
4040                 offset += tvblen;
4041         } else {
4042                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
4043                 offset += bc;
4044         }
4045         return offset;
4046 }
4047
4048 static int
4049 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4050     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4051 {
4052         int tvblen;
4053         tvbuff_t *dcerpc_tvb;
4054
4055         if(bc>datalen){
4056                 /* We have some initial padding bytes. */
4057                 /* XXX - use the data offset here instead? */
4058                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4059                         TRUE);
4060                 offset += bc-datalen;
4061                 bc = datalen;
4062         }
4063         tvblen = tvb_length_remaining(tvb, offset);
4064         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4065         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4066         if(bc>tvblen)
4067                 offset += tvblen;
4068         else
4069                 offset += bc;
4070         return offset;
4071 }
4072
4073 /*
4074  * transporting DCERPC over SMB seems to be implemented in various
4075  * ways. We might just assume it can be done by an almost random
4076  * mix of Trans/Read/Write calls
4077  *
4078  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4079  * and let him sort them out
4080  */
4081 static int
4082 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4083     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4084     guint16 datalen, guint32 ofs, guint16 fid)
4085 {
4086         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4087
4088         DISSECTOR_ASSERT(si);
4089
4090         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
4091                 /* dcerpc call */
4092                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4093                     top_tree, offset, bc, datalen, fid);
4094         } else {
4095                 /* ordinary file data */
4096                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4097         }
4098 }
4099
4100 static int
4101 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4102 {
4103         guint16 cnt=0, bc;
4104         guint8 wc;
4105         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4106         int fid=0;
4107
4108         DISSECTOR_ASSERT(si);
4109
4110         WORD_COUNT;
4111
4112         /* read count */
4113         cnt = tvb_get_letohs(tvb, offset);
4114         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4115         offset += 2;
4116
4117         /* 8 reserved bytes */
4118         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4119         offset += 8;
4120         BYTE_COUNT;
4121
4122         /* buffer format */
4123         CHECK_BYTE_COUNT(1);
4124         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4125         COUNT_BYTES(1);
4126
4127         /* data len */
4128         CHECK_BYTE_COUNT(2);
4129         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4130         COUNT_BYTES(2);
4131
4132         /* file data, might be DCERPC on a pipe */
4133         if(bc){
4134                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4135                     top_tree, offset, bc, bc, 0, (guint16) fid);
4136                 bc = 0;
4137         }
4138
4139         END_OF_SMB
4140
4141         return offset;
4142 }
4143
4144 static int
4145 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4146 {
4147         guint16 cnt, bc;
4148         guint8 wc;
4149
4150         WORD_COUNT;
4151
4152         /* read count */
4153         cnt = tvb_get_letohs(tvb, offset);
4154         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4155         offset += 2;
4156
4157         /* 8 reserved bytes */
4158         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4159         offset += 8;
4160
4161         BYTE_COUNT;
4162
4163         /* buffer format */
4164         CHECK_BYTE_COUNT(1);
4165         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4166         COUNT_BYTES(1);
4167
4168         /* data len */
4169         CHECK_BYTE_COUNT(2);
4170         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4171         COUNT_BYTES(2);
4172
4173         END_OF_SMB
4174
4175         return offset;
4176 }
4177
4178 typedef struct _rw_info_t {
4179         guint32 offset;
4180         guint32 len;
4181         guint16 fid;
4182 } rw_info_t;
4183
4184
4185 static int
4186 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4187 {
4188         guint32 ofs=0;
4189         guint16 cnt=0, bc, fid=0;
4190         guint8 wc;
4191         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4192         rw_info_t *rwi=NULL;
4193
4194         DISSECTOR_ASSERT(si);
4195
4196         WORD_COUNT;
4197
4198         /* fid */
4199         fid = tvb_get_letohs(tvb, offset);
4200         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4201         offset += 2;
4202
4203         /* write count */
4204         cnt = tvb_get_letohs(tvb, offset);
4205         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4206         offset += 2;
4207
4208         /* offset */
4209         ofs = tvb_get_letohl(tvb, offset);
4210         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4211         offset += 4;
4212
4213         if (check_col(pinfo->cinfo, COL_INFO))
4214                 col_append_fstr(pinfo->cinfo, COL_INFO,
4215                                 ", %u byte%s at offset %u", cnt,
4216                                 (cnt == 1) ? "" : "s", ofs);
4217
4218         /* save the offset/len for this transaction */
4219         if(si->sip && !pinfo->fd->flags.visited){
4220                 rwi=se_alloc(sizeof(rw_info_t));
4221                 rwi->offset=ofs;
4222                 rwi->len=cnt;
4223                 rwi->fid=fid;
4224
4225                 si->sip->extra_info_type=SMB_EI_RWINFO;
4226                 si->sip->extra_info=rwi;
4227         }
4228         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4229                 rwi=si->sip->extra_info;
4230         }
4231         if(rwi){
4232                 proto_item *it;
4233
4234                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4235
4236                 PROTO_ITEM_SET_GENERATED(it);
4237                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4238                 PROTO_ITEM_SET_GENERATED(it);
4239         }
4240
4241         /* remaining */
4242         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4243         offset += 2;
4244
4245         BYTE_COUNT;
4246
4247         /* buffer format */
4248         CHECK_BYTE_COUNT(1);
4249         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4250         COUNT_BYTES(1);
4251
4252         /* data len */
4253         CHECK_BYTE_COUNT(2);
4254         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4255         COUNT_BYTES(2);
4256
4257         /* file data, might be DCERPC on a pipe */
4258         if (bc != 0) {
4259                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4260                     top_tree, offset, bc, bc, ofs, fid);
4261                 bc = 0;
4262         }
4263
4264         END_OF_SMB
4265
4266         return offset;
4267 }
4268
4269 static int
4270 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4271 {
4272         guint8 wc;
4273         guint16 bc, cnt;
4274         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4275         rw_info_t *rwi=NULL;
4276
4277         DISSECTOR_ASSERT(si);
4278
4279         WORD_COUNT;
4280
4281         /* write count */
4282         cnt = tvb_get_letohs(tvb, offset);
4283         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4284         offset += 2;
4285
4286         if (check_col(pinfo->cinfo, COL_INFO))
4287                 col_append_fstr(pinfo->cinfo, COL_INFO,
4288                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4289
4290         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4291                 rwi=si->sip->extra_info;
4292         }
4293         if(rwi){
4294                 proto_item *it;
4295
4296                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4297
4298                 PROTO_ITEM_SET_GENERATED(it);
4299                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4300                 PROTO_ITEM_SET_GENERATED(it);
4301         }
4302
4303         BYTE_COUNT;
4304
4305         END_OF_SMB
4306
4307         return offset;
4308 }
4309
4310 static int
4311 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4312 {
4313         guint8 wc;
4314         guint16 bc, fid;
4315
4316         WORD_COUNT;
4317
4318         /* fid */
4319         fid = tvb_get_letohs(tvb, offset);
4320         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4321         offset += 2;
4322
4323         /* lock count */
4324         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
4325         offset += 4;
4326
4327         /* offset */
4328         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4329         offset += 4;
4330
4331         BYTE_COUNT;
4332
4333         END_OF_SMB
4334
4335         return offset;
4336 }
4337
4338 static int
4339 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4340 {
4341         smb_info_t *si = pinfo->private_data;
4342         int fn_len;
4343         const char *fn;
4344         guint8 wc;
4345         guint16 bc;
4346
4347         DISSECTOR_ASSERT(si);
4348
4349         WORD_COUNT;
4350
4351         /* 2 reserved bytes */
4352         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4353         offset += 2;
4354
4355         /* Creation time */
4356         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4357
4358         BYTE_COUNT;
4359
4360         /* buffer format */
4361         CHECK_BYTE_COUNT(1);
4362         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4363         COUNT_BYTES(1);
4364
4365         /* directory name */
4366         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4367                 FALSE, FALSE, &bc);
4368         if (fn == NULL)
4369                 goto endofcommand;
4370         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4371                 fn);
4372         COUNT_BYTES(fn_len);
4373
4374         if (check_col(pinfo->cinfo, COL_INFO)) {
4375                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4376                     format_text(fn, strlen(fn)));
4377         }
4378
4379         END_OF_SMB
4380
4381         return offset;
4382 }
4383
4384 static int
4385 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4386 {
4387         smb_info_t *si = pinfo->private_data;
4388         int fn_len;
4389         const char *fn;
4390         guint8 wc;
4391         guint16 bc, fid;
4392
4393         DISSECTOR_ASSERT(si);
4394
4395         WORD_COUNT;
4396
4397         /* fid */
4398         fid = tvb_get_letohs(tvb, offset);
4399         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
4400         offset += 2;
4401
4402         BYTE_COUNT;
4403
4404         /* buffer format */
4405         CHECK_BYTE_COUNT(1);
4406         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4407         COUNT_BYTES(1);
4408
4409         /* file name */
4410         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4411                 FALSE, FALSE, &bc);
4412         if (fn == NULL)
4413                 goto endofcommand;
4414         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4415                 fn);
4416         COUNT_BYTES(fn_len);
4417
4418         END_OF_SMB
4419
4420         return offset;
4421 }
4422
4423 static const value_string seek_mode_vals[] = {
4424         {0,     "From Start Of File"},
4425         {1,     "From Current Position"},
4426         {2,     "From End Of File"},
4427         {0,     NULL}
4428 };
4429
4430 static int
4431 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4432 {
4433         guint8 wc;
4434         guint16 bc, fid;
4435
4436         WORD_COUNT;
4437
4438         /* fid */
4439         fid = tvb_get_letohs(tvb, offset);
4440         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4441         offset += 2;
4442
4443         /* Seek Mode */
4444         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
4445         offset += 2;
4446
4447         /* offset */
4448         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4449         offset += 4;
4450
4451         BYTE_COUNT;
4452
4453         END_OF_SMB
4454
4455         return offset;
4456 }
4457
4458 static int
4459 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4460 {
4461         guint8 wc;
4462         guint16 bc;
4463
4464         WORD_COUNT;
4465
4466         /* offset */
4467         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4468         offset += 4;
4469
4470         BYTE_COUNT;
4471
4472         END_OF_SMB
4473
4474         return offset;
4475 }
4476
4477 static int
4478 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4479 {
4480         guint8 wc;
4481         guint16 bc, fid;
4482
4483         WORD_COUNT;
4484
4485         /* fid */
4486         fid = tvb_get_letohs(tvb, offset);
4487         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4488         offset += 2;
4489
4490         /* create time */
4491         offset = dissect_smb_datetime(tvb, tree, offset,
4492                 hf_smb_create_time,
4493                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4494
4495         /* access time */
4496         offset = dissect_smb_datetime(tvb, tree, offset,
4497                 hf_smb_access_time,
4498                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4499
4500         /* last write time */
4501         offset = dissect_smb_datetime(tvb, tree, offset,
4502                 hf_smb_last_write_time,
4503                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4504
4505         BYTE_COUNT;
4506
4507         END_OF_SMB
4508
4509         return offset;
4510 }
4511
4512 static int
4513 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4514 {
4515         guint8 wc;
4516         guint16 bc;
4517
4518         WORD_COUNT;
4519
4520         /* create time */
4521         offset = dissect_smb_datetime(tvb, tree, offset,
4522                 hf_smb_create_time,
4523                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4524
4525         /* access time */
4526         offset = dissect_smb_datetime(tvb, tree, offset,
4527                 hf_smb_access_time,
4528                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4529
4530         /* last write time */
4531         offset = dissect_smb_datetime(tvb, tree, offset,
4532                 hf_smb_last_write_time,
4533                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4534
4535         /* data size */
4536         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
4537         offset += 4;
4538
4539         /* allocation size */
4540         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4541         offset += 4;
4542
4543         /* File Attributes */
4544         offset = dissect_file_attributes(tvb, tree, offset, 2);
4545
4546         BYTE_COUNT;
4547
4548         END_OF_SMB
4549
4550         return offset;
4551 }
4552
4553 static int
4554 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4555 {
4556         guint8 wc;
4557         guint16 cnt=0;
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, TRUE, FALSE);
4565         offset += 2;
4566
4567         /* write count */
4568         cnt = tvb_get_letohs(tvb, offset);
4569         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4570         offset += 2;
4571
4572         /* offset */
4573         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4574         offset += 4;
4575
4576         /* last write time */
4577         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4578
4579         if(wc==12){
4580                 /* 12 reserved bytes */
4581                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
4582                 offset += 12;
4583         }
4584
4585         BYTE_COUNT;
4586
4587         /* 1 pad byte */
4588         CHECK_BYTE_COUNT(1);
4589         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
4590         COUNT_BYTES(1);
4591
4592         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4593         bc = 0; /* XXX */
4594
4595         END_OF_SMB
4596
4597         return offset;
4598 }
4599
4600 static int
4601 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4602 {
4603         guint8 wc;
4604         guint16 bc;
4605
4606         WORD_COUNT;
4607
4608         /* write count */
4609         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4610         offset += 2;
4611
4612         BYTE_COUNT;
4613
4614         END_OF_SMB
4615
4616         return offset;
4617 }
4618
4619 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4620    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4621 */
4622 static gchar *
4623 smbext20_timeout_msecs_to_str(gint32 time)
4624 {
4625         gchar *buf;
4626 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4627
4628         if (time <= 0) {
4629                 buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4630                 if (time == 0) {
4631                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4632                 } else if (time == -1) {
4633                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4634                 } else if (time == -2) {
4635                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4636                 } else {
4637                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
4638                 }
4639                 return buf;
4640         }
4641
4642         return time_msecs_to_str(time);
4643 }
4644
4645 static int
4646 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4647 {
4648         guint8 wc;
4649         guint16 bc, fid;
4650         guint32 to;
4651
4652         WORD_COUNT;
4653
4654         /* fid */
4655         fid = tvb_get_letohs(tvb, offset);
4656         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4657         offset += 2;
4658
4659         /* offset */
4660         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4661         offset += 4;
4662
4663         /* max count */
4664         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4665         offset += 2;
4666
4667         /* min count */
4668         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4669         offset += 2;
4670
4671         /* timeout */
4672         to = tvb_get_letohl(tvb, offset);
4673         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4674         offset += 4;
4675
4676         /* 2 reserved bytes */
4677         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4678         offset += 2;
4679
4680         if(wc==10){
4681                 /* high offset */
4682                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4683                 offset += 4;
4684         }
4685
4686         BYTE_COUNT;
4687
4688         END_OF_SMB
4689
4690         return offset;
4691 }
4692
4693 static int
4694 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4695 {
4696         guint8 wc;
4697         guint16 bc;
4698
4699         WORD_COUNT;
4700
4701         /* units */
4702         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
4703         offset += 2;
4704
4705         /* bpu */
4706         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
4707         offset += 2;
4708
4709         /* block size */
4710         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4711         offset += 2;
4712
4713         /* free units */
4714         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4715         offset += 2;
4716
4717         /* 2 reserved bytes */
4718         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4719         offset += 2;
4720
4721         BYTE_COUNT;
4722
4723         END_OF_SMB
4724
4725         return offset;
4726 }
4727
4728 static int
4729 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4730 {
4731         guint8 wc;
4732         guint16 bc, fid;
4733
4734         WORD_COUNT;
4735
4736         /* fid */
4737         fid = tvb_get_letohs(tvb, offset);
4738         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4739         offset += 2;
4740
4741         /* offset */
4742         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4743         offset += 4;
4744
4745         /* max count */
4746         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4747         offset += 2;
4748
4749         /* min count */
4750         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4751         offset += 2;
4752
4753         /* 6 reserved bytes */
4754         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4755         offset += 6;
4756
4757         BYTE_COUNT;
4758
4759         END_OF_SMB
4760
4761         return offset;
4762 }
4763
4764 static int
4765 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4766 {
4767         guint16 datalen=0, bc;
4768         guint8 wc;
4769
4770         WORD_COUNT;
4771
4772         /* offset */
4773         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4774         offset += 4;
4775
4776         /* count */
4777         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4778         offset += 2;
4779
4780         /* 2 reserved bytes */
4781         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4782         offset += 2;
4783
4784         /* data compaction mode */
4785         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4786         offset += 2;
4787
4788         /* 2 reserved bytes */
4789         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4790         offset += 2;
4791
4792         /* data len */
4793         datalen = tvb_get_letohs(tvb, offset);
4794         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4795         offset += 2;
4796
4797         /* data offset */
4798         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4799         offset += 2;
4800
4801         BYTE_COUNT;
4802
4803         /* file data */
4804         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4805         bc = 0;
4806
4807         END_OF_SMB
4808
4809         return offset;
4810 }
4811
4812
4813 static const true_false_string tfs_write_mode_write_through = {
4814         "WRITE THROUGH requested",
4815         "Write through not requested"
4816 };
4817 static const true_false_string tfs_write_mode_return_remaining = {
4818         "RETURN REMAINING (pipe/dev) requested",
4819         "DON'T return remaining (pipe/dev)"
4820 };
4821 static const true_false_string tfs_write_mode_raw = {
4822         "Use WriteRawNamedPipe (pipe)",
4823         "DON'T use WriteRawNamedPipe (pipe)"
4824 };
4825 static const true_false_string tfs_write_mode_message_start = {
4826         "This is the START of a MESSAGE (pipe)",
4827         "This is NOT the start of a message (pipe)"
4828 };
4829 static const true_false_string tfs_write_mode_connectionless = {
4830         "CONNECTIONLESS mode requested",
4831         "Connectionless mode NOT requested"
4832 };
4833
4834 #define WRITE_MODE_CONNECTIONLESS       0x0080
4835 #define WRITE_MODE_MESSAGE_START        0x0008
4836 #define WRITE_MODE_RAW                  0x0004
4837 #define WRITE_MODE_RETURN_REMAINING     0x0002
4838 #define WRITE_MODE_WRITE_THROUGH        0x0001
4839
4840 static int
4841 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4842 {
4843         guint16 mask;
4844         proto_item *item = NULL;
4845         proto_tree *tree = NULL;
4846
4847         mask = tvb_get_letohs(tvb, offset);
4848
4849         if(parent_tree){
4850                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4851                         "Write Mode: 0x%04x", mask);
4852                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4853         }
4854
4855         if(bm&WRITE_MODE_CONNECTIONLESS){
4856                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4857                         tvb, offset, 2, mask);
4858         }
4859         if(bm&WRITE_MODE_MESSAGE_START){
4860                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4861                         tvb, offset, 2, mask);
4862         }
4863         if(bm&WRITE_MODE_RAW){
4864                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4865                         tvb, offset, 2, mask);
4866         }
4867         if(bm&WRITE_MODE_RETURN_REMAINING){
4868                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4869                         tvb, offset, 2, mask);
4870         }
4871         if(bm&WRITE_MODE_WRITE_THROUGH){
4872                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4873                         tvb, offset, 2, mask);
4874         }
4875
4876         offset += 2;
4877         return offset;
4878 }
4879
4880 static int
4881 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4882 {
4883         guint32 to;
4884         guint16 datalen=0, bc, fid;
4885         guint8 wc;
4886
4887         WORD_COUNT;
4888
4889         /* fid */
4890         fid = tvb_get_letohs(tvb, offset);
4891         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4892         offset += 2;
4893
4894         /* total data length */
4895         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4896         offset += 2;
4897
4898         /* 2 reserved bytes */
4899         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4900         offset += 2;
4901
4902         /* offset */
4903         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4904         offset += 4;
4905
4906         /* timeout */
4907         to = tvb_get_letohl(tvb, offset);
4908         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4909         offset += 4;
4910
4911         /* mode */
4912         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4913
4914         /* 4 reserved bytes */
4915         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4916         offset += 4;
4917
4918         /* data len */
4919         datalen = tvb_get_letohs(tvb, offset);
4920         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4921         offset += 2;
4922
4923         /* data offset */
4924         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4925         offset += 2;
4926
4927         BYTE_COUNT;
4928
4929         /* file data */
4930         /* XXX - use the data offset to determine where the data starts? */
4931         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4932         bc = 0;
4933
4934         END_OF_SMB
4935
4936         return offset;
4937 }
4938
4939 static int
4940 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4941 {
4942         guint8 wc;
4943         guint16 bc;
4944
4945         WORD_COUNT;
4946
4947         /* remaining */
4948         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4949         offset += 2;
4950
4951         BYTE_COUNT;
4952
4953         END_OF_SMB
4954
4955         return offset;
4956 }
4957
4958 static int
4959 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4960 {
4961         guint32 to;
4962         guint16 datalen=0, bc, fid;
4963         guint8 wc;
4964
4965         WORD_COUNT;
4966
4967         /* fid */
4968         fid = tvb_get_letohs(tvb, offset);
4969         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4970         offset += 2;
4971
4972         /* total data length */
4973         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4974         offset += 2;
4975
4976         /* 2 reserved bytes */
4977         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4978         offset += 2;
4979
4980         /* offset */
4981         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4982         offset += 4;
4983
4984         /* timeout */
4985         to = tvb_get_letohl(tvb, offset);
4986         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4987         offset += 4;
4988
4989         /* mode */
4990         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4991
4992         /* request mask */
4993         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4994         offset += 4;
4995
4996         /* data len */
4997         datalen = tvb_get_letohs(tvb, offset);
4998         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4999         offset += 2;
5000
5001         /* data offset */
5002         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
5003         offset += 2;
5004
5005         BYTE_COUNT;
5006
5007         /* file data */
5008         /* XXX - use the data offset to determine where the data starts? */
5009         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5010         bc = 0;
5011
5012         END_OF_SMB
5013
5014         return offset;
5015 }
5016
5017 static int
5018 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5019 {
5020         guint8 wc;
5021         guint16 bc;
5022
5023         WORD_COUNT;
5024
5025         /* response mask */
5026         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
5027         offset += 4;
5028
5029         BYTE_COUNT;
5030
5031         END_OF_SMB
5032
5033         return offset;
5034 }
5035
5036 static int
5037 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5038 {
5039         guint8 wc;
5040         guint16 bc;
5041
5042         WORD_COUNT;
5043
5044         /* sid */
5045         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
5046         offset += 2;
5047
5048         BYTE_COUNT;
5049
5050         END_OF_SMB
5051
5052         return offset;
5053 }
5054
5055 static int
5056 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
5057     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5058     gboolean has_find_id)
5059 {
5060         proto_item *item = NULL;
5061         proto_tree *tree = NULL;
5062         smb_info_t *si = pinfo->private_data;
5063         int fn_len;
5064         const char *fn;
5065         char fname[11+1];
5066
5067         DISSECTOR_ASSERT(si);
5068
5069         if(parent_tree){
5070                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5071                         "Resume Key");
5072                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5073         }
5074
5075         /* reserved byte */
5076         CHECK_BYTE_COUNT_SUBR(1);
5077         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5078         COUNT_BYTES_SUBR(1);
5079
5080         /* file name */
5081         fn_len = 11;
5082         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5083                 TRUE, TRUE, bcp);
5084         CHECK_STRING_SUBR(fn);
5085         /* ensure that it's null-terminated */
5086         strncpy(fname, fn, 11);
5087         fname[11] = '\0';
5088         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5089                 fname);
5090         COUNT_BYTES_SUBR(fn_len);
5091
5092         if (has_find_id) {
5093                 CHECK_BYTE_COUNT_SUBR(1);
5094                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
5095                 COUNT_BYTES_SUBR(1);
5096
5097                 /* server cookie */
5098                 CHECK_BYTE_COUNT_SUBR(4);
5099                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
5100                 COUNT_BYTES_SUBR(4);
5101         } else {
5102                 /* server cookie */
5103                 CHECK_BYTE_COUNT_SUBR(5);
5104                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
5105                 COUNT_BYTES_SUBR(5);
5106         }
5107
5108         /* client cookie */
5109         CHECK_BYTE_COUNT_SUBR(4);
5110         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
5111         COUNT_BYTES_SUBR(4);
5112
5113         *trunc = FALSE;
5114         return offset;
5115 }
5116
5117 static int
5118 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5119     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5120     gboolean has_find_id)
5121 {
5122         proto_item *item = NULL;
5123         proto_tree *tree = NULL;
5124         smb_info_t *si = pinfo->private_data;
5125         int fn_len;
5126         const char *fn;
5127         char fname[13+1];
5128
5129         DISSECTOR_ASSERT(si);
5130
5131         if(parent_tree){
5132                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5133                         "Directory Information");
5134                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5135         }
5136
5137         /* resume key */
5138         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5139             trunc, has_find_id);
5140         if (*trunc)
5141                 return offset;
5142
5143         /* File Attributes */
5144         CHECK_BYTE_COUNT_SUBR(1);
5145         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5146         *bcp -= 1;
5147
5148         /* last write time */
5149         CHECK_BYTE_COUNT_SUBR(4);
5150         offset = dissect_smb_datetime(tvb, tree, offset,
5151                 hf_smb_last_write_time,
5152                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5153                 TRUE);
5154         *bcp -= 4;
5155
5156         /* File Size */
5157         CHECK_BYTE_COUNT_SUBR(4);
5158         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5159         COUNT_BYTES_SUBR(4);
5160
5161         /* file name */
5162         fn_len = 13;
5163         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5164                 TRUE, TRUE, bcp);
5165         CHECK_STRING_SUBR(fn);
5166         /* ensure that it's null-terminated */
5167         strncpy(fname, fn, 13);
5168         fname[13] = '\0';
5169         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5170                 fname);
5171         COUNT_BYTES_SUBR(fn_len);
5172
5173         *trunc = FALSE;
5174         return offset;
5175 }
5176
5177
5178 static int
5179 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5180     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5181     gboolean has_find_id)
5182 {
5183         smb_info_t *si = pinfo->private_data;
5184         int fn_len;
5185         const char *fn;
5186         guint16 rkl;
5187         guint8 wc;
5188         guint16 bc;
5189         gboolean trunc;
5190
5191         DISSECTOR_ASSERT(si);
5192
5193         WORD_COUNT;
5194
5195         /* max count */
5196         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5197         offset += 2;
5198
5199         /* Search Attributes */
5200         offset = dissect_search_attributes(tvb, tree, offset);
5201
5202         BYTE_COUNT;
5203
5204         /* buffer format */
5205         CHECK_BYTE_COUNT(1);
5206         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5207         COUNT_BYTES(1);
5208
5209         /* file name */
5210         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5211                 TRUE, FALSE, &bc);
5212         if (fn == NULL)
5213                 goto endofcommand;
5214         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5215                 fn);
5216         COUNT_BYTES(fn_len);
5217
5218         if (check_col(pinfo->cinfo, COL_INFO)) {
5219                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5220                     format_text(fn, strlen(fn)));
5221         }
5222
5223         /* buffer format */
5224         CHECK_BYTE_COUNT(1);
5225         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5226         COUNT_BYTES(1);
5227
5228         /* resume key length */
5229         CHECK_BYTE_COUNT(2);
5230         rkl = tvb_get_letohs(tvb, offset);
5231         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5232         COUNT_BYTES(2);
5233
5234         /* resume key */
5235         if(rkl){
5236                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5237                     &bc, &trunc, has_find_id);
5238                 if (trunc)
5239                         goto endofcommand;
5240         }
5241
5242         END_OF_SMB
5243
5244         return offset;
5245 }
5246
5247 static int
5248 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5249     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5250 {
5251         return dissect_search_find_request(tvb, pinfo, tree, offset,
5252             smb_tree, FALSE);
5253 }
5254
5255 static int
5256 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5257     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5258 {
5259         return dissect_search_find_request(tvb, pinfo, tree, offset,
5260             smb_tree, TRUE);
5261 }
5262
5263 static int
5264 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5265     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5266 {
5267         return dissect_search_find_request(tvb, pinfo, tree, offset,
5268             smb_tree, TRUE);
5269 }
5270
5271 static int
5272 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5273     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5274     gboolean has_find_id)
5275 {
5276         guint16 count=0;
5277         guint8 wc;
5278         guint16 bc;
5279         gboolean trunc;
5280
5281         WORD_COUNT;
5282
5283         /* count */
5284         count = tvb_get_letohs(tvb, offset);
5285         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5286         offset += 2;
5287
5288         BYTE_COUNT;
5289
5290         /* buffer format */
5291         CHECK_BYTE_COUNT(1);
5292         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5293         COUNT_BYTES(1);
5294
5295         /* data len */
5296         CHECK_BYTE_COUNT(2);
5297         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
5298         COUNT_BYTES(2);
5299
5300         while(count--){
5301                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5302                     &bc, &trunc, has_find_id);
5303                 if (trunc)
5304                         goto endofcommand;
5305         }
5306
5307         END_OF_SMB
5308
5309         return offset;
5310 }
5311
5312 static int
5313 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5314 {
5315         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5316             FALSE);
5317 }
5318
5319 static int
5320 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5321 {
5322         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5323             TRUE);
5324 }
5325
5326 static int
5327 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5328     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5329 {
5330         guint8 wc;
5331         guint16 bc;
5332         guint16 data_len;
5333
5334         WORD_COUNT;
5335
5336         /* reserved */
5337         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5338         offset += 2;
5339
5340         BYTE_COUNT;
5341
5342         /* buffer format */
5343         CHECK_BYTE_COUNT(1);
5344         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5345         COUNT_BYTES(1);
5346
5347         /* data len */
5348         CHECK_BYTE_COUNT(2);
5349         data_len = tvb_get_ntohs(tvb, offset);
5350         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5351         COUNT_BYTES(2);
5352
5353         if (data_len != 0) {
5354                 CHECK_BYTE_COUNT(data_len);
5355                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5356                     data_len, TRUE);
5357                 COUNT_BYTES(data_len);
5358         }
5359
5360         END_OF_SMB
5361
5362         return offset;
5363 }
5364
5365 static const value_string locking_ol_vals[] = {
5366         {0,     "Client is not holding oplock on this file"},
5367         {1,     "Level 2 oplock currently held by client"},
5368         {0, NULL}
5369 };
5370
5371 static const true_false_string tfs_lock_type_large = {
5372         "Large file locking format requested",
5373         "Large file locking format not requested"
5374 };
5375 static const true_false_string tfs_lock_type_cancel = {
5376         "Cancel outstanding lock request",
5377         "Don't cancel outstanding lock request"
5378 };
5379 static const true_false_string tfs_lock_type_change = {
5380         "Change lock type",
5381         "Don't change lock type"
5382 };
5383 static const true_false_string tfs_lock_type_oplock = {
5384         "This is an oplock break notification/response",
5385         "This is not an oplock break notification/response"
5386 };
5387 static const true_false_string tfs_lock_type_shared = {
5388         "This is a shared lock",
5389         "This is an exclusive lock"
5390 };
5391 static int
5392 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5393 {
5394         guint8  wc, cmd=0xff, lt=0, ol=0;
5395         guint16 andxoffset=0, un=0, ln=0, bc, fid, num_lock=0, num_unlock=0;
5396         guint32 to;
5397         proto_item *litem = NULL;
5398         proto_tree *ltree = NULL;
5399         proto_item *it = NULL;
5400         proto_tree *tr = NULL;
5401         int old_offset = offset;
5402         smb_info_t *si = pinfo->private_data;
5403         smb_locking_saved_info_t *ld=NULL;
5404
5405
5406         DISSECTOR_ASSERT(si);
5407
5408         WORD_COUNT;
5409
5410         /* next smb command */
5411         cmd = tvb_get_guint8(tvb, offset);
5412         if(cmd!=0xff){
5413                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5414         } else {
5415                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5416         }
5417         offset += 1;
5418
5419         /* reserved byte */
5420         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5421         offset += 1;
5422
5423         /* andxoffset */
5424         andxoffset = tvb_get_letohs(tvb, offset);
5425         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5426         offset += 2;
5427
5428         /* fid */
5429         fid = tvb_get_letohs(tvb, offset);
5430         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5431         offset += 2;
5432
5433         /* lock type */
5434         lt = tvb_get_guint8(tvb, offset);
5435         if(tree){
5436                 litem = proto_tree_add_text(tree, tvb, offset, 1,
5437                         "Lock Type: 0x%02x", lt);
5438                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5439         }
5440         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5441                 tvb, offset, 1, lt);
5442         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5443                 tvb, offset, 1, lt);
5444         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5445                 tvb, offset, 1, lt);
5446         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5447                 tvb, offset, 1, lt);
5448         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5449                 tvb, offset, 1, lt);
5450         offset += 1;
5451
5452         /* oplock level */
5453         ol = tvb_get_guint8(tvb, offset);
5454         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
5455         offset += 1;
5456
5457         /* timeout */
5458         to = tvb_get_letohl(tvb, offset);
5459         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5460         offset += 4;
5461
5462         /* number of unlocks */
5463         un = tvb_get_letohs(tvb, offset);
5464         num_unlock=un;
5465         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5466         offset += 2;
5467
5468         /* number of locks */
5469         ln = tvb_get_letohs(tvb, offset);
5470         num_lock=ln;
5471         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5472         offset += 2;
5473
5474         BYTE_COUNT;
5475
5476         /* store the locking data for the response */
5477         if((!pinfo->fd->flags.visited) && si->sip){
5478                 ld=se_alloc(sizeof(smb_locking_saved_info_t));
5479                 ld->type=lt;
5480                 ld->oplock_level= ol;
5481                 ld->num_lock=num_lock;
5482                 ld->num_unlock=num_unlock;
5483                 ld->locks=NULL;
5484                 ld->unlocks=NULL;
5485                 si->sip->extra_info_type=SMB_EI_LOCKDATA;
5486                 si->sip->extra_info=ld;
5487         }
5488
5489         /* unlocks */
5490         if(un){
5491                 old_offset = offset;
5492
5493                 it = proto_tree_add_text(tree, tvb, offset, -1,
5494                         "Unlocks");
5495                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5496                 while(un--){
5497                         proto_item *litem = NULL;
5498                         proto_tree *ltree = NULL;
5499                         if(lt&0x10){
5500                                 guint64 val;
5501                                 guint16 lock_pid;
5502                                 guint64 lock_offset;
5503                                 guint64 lock_length;
5504
5505                                 /* large lock format */
5506                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5507                                         "Unlock");
5508                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5509
5510                                 /* PID */
5511                                 CHECK_BYTE_COUNT(2);
5512                                 lock_pid=tvb_get_letohs(tvb, offset);
5513                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5514                                 COUNT_BYTES(2);
5515
5516                                 /* 2 reserved bytes */
5517                                 CHECK_BYTE_COUNT(2);
5518                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5519                                 COUNT_BYTES(2);
5520
5521                                 /* offset */
5522                                 CHECK_BYTE_COUNT(8);
5523                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5524                                     | tvb_get_letohl(tvb, offset+4);
5525                                 lock_offset=val;
5526                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5527                                 COUNT_BYTES(8);
5528
5529                                 /* length */
5530                                 CHECK_BYTE_COUNT(8);
5531                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5532                                     | tvb_get_letohl(tvb, offset+4);
5533                                 lock_length=val;
5534                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5535                                 COUNT_BYTES(8);
5536
5537                                 /* remember the unlock for the reply */
5538                                 if(ld){
5539                                         smb_lock_info_t *li;
5540                                         li=se_alloc(sizeof(smb_lock_info_t));
5541                                         li->next=ld->unlocks;
5542                                         ld->unlocks=li;
5543                                         li->pid=lock_pid;
5544                                         li->offset=lock_offset;
5545                                         li->length=lock_length;
5546                                 }
5547                         } else {
5548                                 /* normal lock format */
5549                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5550                                         "Unlock");
5551                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5552
5553                                 /* PID */
5554                                 CHECK_BYTE_COUNT(2);
5555                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5556                                 COUNT_BYTES(2);
5557
5558                                 /* offset */
5559                                 CHECK_BYTE_COUNT(4);
5560                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5561                                 COUNT_BYTES(4);
5562
5563                                 /* lock count */
5564                                 CHECK_BYTE_COUNT(4);
5565                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5566                                 COUNT_BYTES(4);
5567                         }
5568                 }
5569                 proto_item_set_len(it, offset-old_offset);
5570                 it = NULL;
5571         }
5572
5573         /* locks */
5574         if(ln){
5575                 old_offset = offset;
5576
5577                 it = proto_tree_add_text(tree, tvb, offset, -1,
5578                         "Locks");
5579                 tr = proto_item_add_subtree(it, ett_smb_locks);
5580                 while(ln--){
5581                         proto_item *litem = NULL;
5582                         proto_tree *ltree = NULL;
5583                         if(lt&0x10){
5584                                 guint64 val;
5585                                 guint16 lock_pid;
5586                                 guint64 lock_offset;
5587                                 guint64 lock_length;
5588
5589                                 /* large lock format */
5590                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5591                                         "Lock");
5592                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5593
5594                                 /* PID */
5595                                 CHECK_BYTE_COUNT(2);
5596                                 lock_pid=tvb_get_letohs(tvb, offset);
5597                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5598                                 COUNT_BYTES(2);
5599
5600                                 /* 2 reserved bytes */
5601                                 CHECK_BYTE_COUNT(2);
5602                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5603                                 COUNT_BYTES(2);
5604
5605                                 /* offset */
5606                                 CHECK_BYTE_COUNT(8);
5607                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5608                                     | tvb_get_letohl(tvb, offset+4);
5609                                 lock_offset=val;
5610                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5611                                 COUNT_BYTES(8);
5612
5613                                 /* length */
5614                                 CHECK_BYTE_COUNT(8);
5615                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5616                                     | tvb_get_letohl(tvb, offset+4);
5617                                 lock_length=val;
5618                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5619                                 COUNT_BYTES(8);
5620
5621                                 /* remember the lock for the reply */
5622                                 if(ld){
5623                                         smb_lock_info_t *li;
5624                                         li=se_alloc(sizeof(smb_lock_info_t));
5625                                         li->next=ld->locks;
5626                                         ld->locks=li;
5627                                         li->pid=lock_pid;
5628                                         li->offset=lock_offset;
5629                                         li->length=lock_length;
5630                                 }
5631                         } else {
5632                                 /* normal lock format */
5633                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5634                                         "Lock");
5635                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5636
5637                                 /* PID */
5638                                 CHECK_BYTE_COUNT(2);
5639                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5640                                 COUNT_BYTES(2);
5641
5642                                 /* offset */
5643                                 CHECK_BYTE_COUNT(4);
5644                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5645                                 COUNT_BYTES(4);
5646
5647                                 /* lock count */
5648                                 CHECK_BYTE_COUNT(4);
5649                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5650                                 COUNT_BYTES(4);
5651                         }
5652                 }
5653                 proto_item_set_len(it, offset-old_offset);
5654                 it = NULL;
5655         }
5656
5657         END_OF_SMB
5658
5659         if (it != NULL) {
5660                 /*
5661                  * We ran out of byte count in the middle of dissecting
5662                  * the locks or the unlocks; set the site of the item
5663                  * we were dissecting.
5664                  */
5665                 proto_item_set_len(it, offset-old_offset);
5666         }
5667
5668         if (cmd != 0xff) {      /* there is an andX command */
5669                 if (andxoffset < offset)
5670                         THROW(ReportedBoundsError);
5671                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5672         }
5673
5674         return offset;
5675 }
5676
5677 static int
5678 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5679 {
5680         guint8  wc, cmd=0xff;
5681         guint16 andxoffset=0;
5682         guint16 bc;
5683         smb_info_t *si;
5684
5685         si = (smb_info_t *)pinfo->private_data;
5686         DISSECTOR_ASSERT(si);
5687
5688         /* print the lock info from the request */
5689         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_LOCKDATA) {
5690                 smb_locking_saved_info_t *ld;
5691                 proto_item *litem = NULL;
5692                 proto_tree *ltree = NULL;
5693
5694                 ld = si->sip->extra_info;
5695                 if (ld != NULL) {
5696                         proto_item *lit = NULL;
5697                         proto_tree *ltr = NULL;
5698                         smb_lock_info_t *li;
5699                         if(tree){
5700                                 litem = proto_tree_add_text(tree, tvb, 0, 0,
5701                                         "Lock Type: 0x%02x", ld->type);
5702                                 PROTO_ITEM_SET_GENERATED(litem);
5703                                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5704                         }
5705
5706                         proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
5707                         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
5708                         proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
5709                         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
5710                         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
5711                         proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
5712                         proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
5713                         proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
5714                                 
5715                         lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
5716                         ltr = proto_item_add_subtree(lit, ett_smb_lock);
5717                         li=ld->locks;
5718                         while(li){
5719                                 proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5720                                 proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5721                                 proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5722                                 li=li->next;
5723                         }
5724                         lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
5725                         ltr = proto_item_add_subtree(lit, ett_smb_unlock);
5726                         li=ld->unlocks;
5727                         while(li){
5728                                 proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5729                                 proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5730                                 proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5731                                 li=li->next;
5732                         }
5733                 }
5734         }
5735
5736         WORD_COUNT;
5737
5738         /* next smb command */
5739         cmd = tvb_get_guint8(tvb, offset);
5740         if(cmd!=0xff){
5741                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5742         } else {
5743                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5744         }
5745         offset += 1;
5746
5747         /* reserved byte */
5748         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5749         offset += 1;
5750
5751         /* andxoffset */
5752         andxoffset = tvb_get_letohs(tvb, offset);
5753         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5754         offset += 2;
5755
5756         BYTE_COUNT;
5757
5758         END_OF_SMB
5759
5760         if (cmd != 0xff) {      /* there is an andX command */
5761                 if (andxoffset < offset)
5762                         THROW(ReportedBoundsError);
5763                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5764         }
5765
5766         return offset;
5767 }
5768
5769
5770 const value_string oa_open_vals[] = {
5771         { 0,            "No action taken?"},
5772         { 1,            "The file existed and was opened"},
5773         { 2,            "The file did not exist but was created"},
5774         { 3,            "The file existed and was truncated"},
5775         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
5776         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
5777         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
5778         {0,     NULL}
5779 };
5780 static const true_false_string tfs_oa_lock = {
5781         "File is currently opened only by this user",
5782         "File is opened by another user (or mode not supported by server)"
5783 };
5784 static int
5785 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5786 {
5787         guint16 mask;
5788         proto_item *item = NULL;
5789         proto_tree *tree = NULL;
5790
5791         mask = tvb_get_letohs(tvb, offset);
5792
5793         if(parent_tree){
5794                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5795                         "Action: 0x%04x", mask);
5796                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5797         }
5798
5799         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5800                 tvb, offset, 2, mask);
5801         proto_tree_add_uint(tree, hf_smb_open_action_open,
5802                 tvb, offset, 2, mask);
5803
5804         offset += 2;
5805
5806         return offset;
5807 }
5808
5809 static const true_false_string tfs_open_flags_add_info = {
5810         "Additional information requested",
5811         "Additional information not requested"
5812 };
5813 static const true_false_string tfs_open_flags_ex_oplock = {
5814         "Exclusive oplock requested",
5815         "Exclusive oplock not requested"
5816 };
5817 static const true_false_string tfs_open_flags_batch_oplock = {
5818         "Batch oplock requested",
5819         "Batch oplock not requested"
5820 };
5821 static const true_false_string tfs_open_flags_ealen = {
5822         "Total length of EAs requested",
5823         "Total length of EAs not requested"
5824 };
5825 static int
5826 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5827 {
5828         guint16 mask;
5829         proto_item *item = NULL;
5830         proto_tree *tree = NULL;
5831
5832         mask = tvb_get_letohs(tvb, offset);
5833
5834         if(parent_tree){
5835                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5836                         "Flags: 0x%04x", mask);
5837                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5838         }
5839
5840         if(bm&0x0001){
5841                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5842                         tvb, offset, 2, mask);
5843         }
5844         if(bm&0x0002){
5845                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5846                         tvb, offset, 2, mask);
5847         }
5848         if(bm&0x0004){
5849                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5850                         tvb, offset, 2, mask);
5851         }
5852         if(bm&0x0008){
5853                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5854                         tvb, offset, 2, mask);
5855         }
5856
5857         offset += 2;
5858
5859         return offset;
5860 }
5861
5862 static const value_string filetype_vals[] = {
5863         { 0,            "Disk file or directory"},
5864         { 1,            "Named pipe in byte mode"},
5865         { 2,            "Named pipe in message mode"},
5866         { 3,            "Spooled printer"},
5867         {0, NULL}
5868 };
5869 static int
5870 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5871 {
5872         guint8  wc, cmd=0xff;
5873         guint16 andxoffset=0, bc;
5874         guint32 to;
5875         smb_info_t *si = pinfo->private_data;
5876         int fn_len;
5877         const char *fn;
5878
5879         DISSECTOR_ASSERT(si);
5880
5881         WORD_COUNT;
5882
5883         /* next smb command */
5884         cmd = tvb_get_guint8(tvb, offset);
5885         if(cmd!=0xff){
5886                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5887         } else {
5888                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5889         }
5890         offset += 1;
5891
5892         /* reserved byte */
5893         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5894         offset += 1;
5895
5896         /* andxoffset */
5897         andxoffset = tvb_get_letohs(tvb, offset);
5898         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5899         offset += 2;
5900
5901         /* open flags */
5902         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5903
5904         /* desired access */
5905         offset = dissect_access(tvb, tree, offset, "Desired");
5906
5907         /* Search Attributes */
5908         offset = dissect_search_attributes(tvb, tree, offset);
5909
5910         /* File Attributes */
5911         offset = dissect_file_attributes(tvb, tree, offset, 2);
5912
5913         /* creation time */
5914         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5915
5916         /* open function */
5917         offset = dissect_open_function(tvb, tree, offset);
5918
5919         /* allocation size */
5920         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5921         offset += 4;
5922
5923         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
5924         to = tvb_get_letohl(tvb, offset);
5925         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5926         offset += 4;
5927
5928         /* 4 reserved bytes */
5929         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5930         offset += 4;
5931
5932         BYTE_COUNT;
5933
5934         /* file name */
5935         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5936                 FALSE, FALSE, &bc);
5937         if (fn == NULL)
5938                 goto endofcommand;
5939         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5940                 fn);
5941         COUNT_BYTES(fn_len);
5942
5943         if (check_col(pinfo->cinfo, COL_INFO)) {
5944                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
5945                     format_text(fn, strlen(fn)));
5946         }
5947
5948         END_OF_SMB
5949
5950         if (cmd != 0xff) {      /* there is an andX command */
5951                 if (andxoffset < offset)
5952                         THROW(ReportedBoundsError);
5953                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5954         }
5955
5956         return offset;
5957 }
5958
5959 static const true_false_string tfs_ipc_state_nonblocking = {
5960         "Reads/writes return immediately if no data available",
5961         "Reads/writes block if no data available"
5962 };
5963 static const value_string ipc_state_endpoint_vals[] = {
5964         { 0,            "Consumer end of pipe"},
5965         { 1,            "Server end of pipe"},
5966         {0,     NULL}
5967 };
5968 static const value_string ipc_state_pipe_type_vals[] = {
5969         { 0,            "Byte stream pipe"},
5970         { 1,            "Message pipe"},
5971         {0,     NULL}
5972 };
5973 static const value_string ipc_state_read_mode_vals[] = {
5974         { 0,            "Read pipe as a byte stream"},
5975         { 1,            "Read messages from pipe"},
5976         {0,     NULL}
5977 };
5978
5979 int
5980 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5981     gboolean setstate)
5982 {
5983         guint16 mask;
5984         proto_item *item = NULL;
5985         proto_tree *tree = NULL;
5986
5987         mask = tvb_get_letohs(tvb, offset);
5988
5989         if(parent_tree){
5990                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5991                         "IPC State: 0x%04x", mask);
5992                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5993         }
5994
5995         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5996                 tvb, offset, 2, mask);
5997         if (!setstate) {
5998                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5999                         tvb, offset, 2, mask);
6000                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6001                         tvb, offset, 2, mask);
6002         }
6003         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6004                 tvb, offset, 2, mask);
6005         if (!setstate) {
6006                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6007                         tvb, offset, 2, mask);
6008         }
6009
6010         offset += 2;
6011
6012         return offset;
6013 }
6014
6015 static int
6016 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6017 {
6018         guint8  wc, cmd=0xff;
6019         guint16 andxoffset=0, bc;
6020         guint16 fid;
6021
6022         WORD_COUNT;
6023
6024         /* next smb command */
6025         cmd = tvb_get_guint8(tvb, offset);
6026         if(cmd!=0xff){
6027                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6028         } else {
6029                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6030         }
6031         offset += 1;
6032
6033         /* reserved byte */
6034         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6035         offset += 1;
6036
6037         /* andxoffset */
6038         andxoffset = tvb_get_letohs(tvb, offset);
6039         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6040         offset += 2;
6041
6042         /* fid */
6043         fid = tvb_get_letohs(tvb, offset);
6044         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
6045         offset += 2;
6046
6047         /* File Attributes */
6048         offset = dissect_file_attributes(tvb, tree, offset, 2);
6049
6050         /* last write time */
6051         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6052
6053         /* File Size */
6054         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
6055         offset += 4;
6056
6057         /* granted access */
6058         offset = dissect_access(tvb, tree, offset, "Granted");
6059
6060         /* File Type */
6061         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
6062         offset += 2;
6063
6064         /* IPC State */
6065         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6066
6067         /* open_action */
6068         offset = dissect_open_action(tvb, tree, offset);
6069
6070         /* server fid */
6071         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
6072         offset += 4;
6073
6074         /* 2 reserved bytes */
6075         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6076         offset += 2;
6077
6078         BYTE_COUNT;
6079
6080         END_OF_SMB
6081
6082         if (cmd != 0xff) {      /* there is an andX command */
6083                 if (andxoffset < offset)
6084                         THROW(ReportedBoundsError);
6085                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6086         }
6087
6088         return offset;
6089 }
6090
6091 static int
6092 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6093 {
6094         guint8  wc, cmd=0xff;
6095         guint16 andxoffset=0, bc, maxcnt_low;
6096         guint32 maxcnt_high;
6097         guint32 maxcnt=0;
6098         guint32 ofs = 0;
6099         smb_info_t *si= (smb_info_t *)pinfo->private_data;
6100         unsigned int fid;
6101         rw_info_t *rwi=NULL;
6102
6103         
6104         DISSECTOR_ASSERT(si);
6105
6106         WORD_COUNT;
6107
6108         /* next smb command */
6109         cmd = tvb_get_guint8(tvb, offset);
6110         if(cmd!=0xff){
6111                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6112         } else {
6113                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6114         }
6115         offset += 1;
6116
6117         /* reserved byte */
6118         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6119         offset += 1;
6120
6121         /* andxoffset */
6122         andxoffset = tvb_get_letohs(tvb, offset);
6123         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6124         offset += 2;
6125
6126         /* fid */
6127         fid = tvb_get_letohs(tvb, offset);
6128         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6129         offset += 2;
6130
6131         /* offset */
6132         ofs = tvb_get_letohl(tvb, offset);
6133         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6134         offset += 4;
6135
6136         /* max count low */
6137         maxcnt_low = tvb_get_letohs(tvb, offset);
6138         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6139         offset += 2;
6140
6141         /* min count */
6142         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
6143         offset += 2;
6144
6145         /*
6146          * max count high
6147          *
6148          * XXX - we should really only do this in case we have seen
6149          * LARGE FILE being negotiated.  Unfortunately, we might not
6150          * have seen the negotiation phase in the capture....
6151          *
6152          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6153          * it's 32 bits, but the description says "High 16 bits of
6154          * MaxCount if CAP_LARGE_READX".
6155          *
6156          * The SMB File Sharing Protocol Extensions Version 2.0,
6157          * Document Version 3.3 spec doesn't speak of an extra 16
6158          * bits in max count, but it does show a 32-bit timeout
6159          * after the min count field.
6160          *
6161          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
6162          * high count and a 16-bit reserved field.
6163          *
6164          * We fetch and display it as 32 bits.
6165          * 
6166          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6167          * bytes and we just ignore it.
6168          */
6169         maxcnt_high = tvb_get_letohl(tvb, offset);
6170         if(maxcnt_high==0xffffffff){
6171                 maxcnt_high=0;
6172         } else {
6173                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6174         }
6175
6176         offset += 4;
6177
6178         maxcnt=maxcnt_high;
6179         maxcnt=(maxcnt<<16)|maxcnt_low;
6180
6181         if (check_col(pinfo->cinfo, COL_INFO))
6182                 col_append_fstr(pinfo->cinfo, COL_INFO,
6183                                 ", %u byte%s at offset %u", maxcnt,
6184                                 (maxcnt == 1) ? "" : "s", ofs);
6185
6186         /* save the offset/len for this transaction */
6187         if(si->sip && !pinfo->fd->flags.visited){
6188                 rwi=se_alloc(sizeof(rw_info_t));
6189                 rwi->offset=ofs;
6190                 rwi->len=maxcnt;
6191                 rwi->fid=fid;
6192
6193                 si->sip->extra_info_type=SMB_EI_RWINFO;
6194                 si->sip->extra_info=rwi;
6195         }
6196         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6197                 rwi=si->sip->extra_info;
6198         }
6199         if(rwi){
6200                 proto_item *it;
6201
6202                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6203
6204                 PROTO_ITEM_SET_GENERATED(it);
6205                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6206                 PROTO_ITEM_SET_GENERATED(it);
6207         }
6208
6209         /* remaining */
6210         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6211         offset += 2;
6212
6213         if(wc==12){
6214                 /* high offset */
6215                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6216                 offset += 4;
6217         }
6218
6219         BYTE_COUNT;
6220
6221         END_OF_SMB
6222
6223         if (cmd != 0xff) {      /* there is an andX command */
6224                 if (andxoffset < offset)
6225                         THROW(ReportedBoundsError);
6226                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6227         }
6228
6229         return offset;
6230 }
6231
6232 static int
6233 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6234 {
6235         guint8  wc, cmd=0xff;
6236         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
6237         guint32 datalen=0, datalen_high;
6238         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6239         int fid=0;
6240         rw_info_t *rwi=NULL;
6241
6242         DISSECTOR_ASSERT(si);
6243
6244         WORD_COUNT;
6245
6246         /* next smb command */
6247         cmd = tvb_get_guint8(tvb, offset);
6248         if(cmd!=0xff){
6249                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6250         } else {
6251                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6252         }
6253         offset += 1;
6254
6255         /* reserved byte */
6256         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6257         offset += 1;
6258
6259         /* andxoffset */
6260         andxoffset = tvb_get_letohs(tvb, offset);
6261         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6262         offset += 2;
6263
6264         /* If we have seen the request, then print which FID this refers to */
6265         /* first check if we have seen the request */
6266         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6267                 fid=GPOINTER_TO_INT(si->sip->extra_info);
6268                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
6269         }
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                 /* we need the fid for the call to dcerpc below */
6284                 fid=rwi->fid;
6285         }
6286
6287         /* remaining */
6288         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6289         offset += 2;
6290
6291         /* data compaction mode */
6292         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
6293         offset += 2;
6294
6295         /* 2 reserved bytes */
6296         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6297         offset += 2;
6298
6299         /* data len low */
6300         datalen_low = tvb_get_letohs(tvb, offset);
6301         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6302         offset += 2;
6303
6304         /* data offset */
6305         dataoffset=tvb_get_letohs(tvb, offset);
6306         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6307         offset += 2;
6308
6309         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6310         /* data length high */
6311         datalen_high = tvb_get_letohl(tvb, offset);
6312         if(datalen_high==0xffffffff){
6313                 datalen_high=0;
6314         } else {
6315                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6316         }
6317         offset += 4;
6318
6319         datalen=datalen_high;
6320         datalen=(datalen<<16)|datalen_low;
6321
6322
6323         if (check_col(pinfo->cinfo, COL_INFO))
6324                 col_append_fstr(pinfo->cinfo, COL_INFO,
6325                                 ", %u byte%s", datalen,
6326                                 (datalen == 1) ? "" : "s");
6327
6328
6329         /* 6 reserved bytes */
6330         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
6331         offset += 6;
6332
6333         BYTE_COUNT;
6334
6335         /* file data, might be DCERPC on a pipe */
6336         if(bc){
6337                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6338                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6339                 bc = 0;
6340         }
6341
6342         END_OF_SMB
6343
6344         if (cmd != 0xff) {      /* there is an andX command */
6345                 if (andxoffset < offset)
6346                         THROW(ReportedBoundsError);
6347                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6348         }
6349
6350         return offset;
6351 }
6352
6353 static int
6354 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6355 {
6356         guint32 ofs=0;
6357         guint8  wc, cmd=0xff;
6358         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
6359         guint32 datalen=0;
6360         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6361         unsigned int fid=0;
6362         guint16 mode = 0;
6363         rw_info_t *rwi=NULL;
6364
6365
6366         DISSECTOR_ASSERT(si);
6367
6368         WORD_COUNT;
6369
6370         /* next smb command */
6371         cmd = tvb_get_guint8(tvb, offset);
6372         if(cmd!=0xff){
6373                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6374         } else {
6375                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6376         }
6377         offset += 1;
6378
6379         /* reserved byte */
6380         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6381         offset += 1;
6382
6383         /* andxoffset */
6384         andxoffset = tvb_get_letohs(tvb, offset);
6385         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6386         offset += 2;
6387
6388         /* fid */
6389         fid = tvb_get_letohs(tvb, offset);
6390         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6391         offset += 2;
6392
6393         /* offset */
6394         ofs = tvb_get_letohl(tvb, offset);
6395         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6396         offset += 4;
6397
6398         /* reserved */
6399         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6400         offset += 4;
6401
6402         /* mode */
6403         mode = tvb_get_letohs(tvb, offset);
6404         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6405
6406         /* remaining */
6407         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6408         offset += 2;
6409
6410         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6411         /* data length high */
6412         datalen_high = tvb_get_letohs(tvb, offset);
6413         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6414         offset += 2;
6415
6416         /* data len low */
6417         datalen_low = tvb_get_letohs(tvb, offset);
6418         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6419         offset += 2;
6420
6421         datalen=datalen_high;
6422         datalen=(datalen<<16)|datalen_low;
6423
6424         /* data offset */
6425         dataoffset=tvb_get_letohs(tvb, offset);
6426         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6427         offset += 2;
6428
6429         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
6430         if (check_col(pinfo->cinfo, COL_INFO))
6431                 col_append_fstr(pinfo->cinfo, COL_INFO,
6432                                 ", %u byte%s at offset %u", datalen,
6433                                 (datalen == 1) ? "" : "s", ofs);
6434
6435         /* save the offset/len for this transaction */
6436         if(si->sip && !pinfo->fd->flags.visited){
6437                 rwi=se_alloc(sizeof(rw_info_t));
6438                 rwi->offset=ofs;
6439                 rwi->len=datalen;
6440                 rwi->fid=fid;
6441
6442                 si->sip->extra_info_type=SMB_EI_RWINFO;
6443                 si->sip->extra_info=rwi;
6444         }
6445         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6446                 rwi=si->sip->extra_info;
6447         }
6448         if(rwi){
6449                 proto_item *it;
6450
6451                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6452
6453                 PROTO_ITEM_SET_GENERATED(it);
6454                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6455                 PROTO_ITEM_SET_GENERATED(it);
6456         }
6457
6458
6459         if(wc==14){
6460                 /* high offset */
6461                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6462                 offset += 4;
6463         }
6464
6465         BYTE_COUNT;
6466
6467         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6468            the first two bytes of the payload is the length of the data.
6469            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6470            be over the IPC$ share and thus they all transport DCERPC.
6471            (if we didnt already know that from the TreeConnect call)
6472         */
6473         if(mode&WRITE_MODE_MESSAGE_START){
6474                 if(mode&WRITE_MODE_RAW){
6475                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
6476                         offset += 2;
6477                         dataoffset += 2;
6478                         bc -= 2;
6479                         datalen -= 2;
6480                 }
6481                 if(!pinfo->fd->flags.visited){
6482                         /* In case we did not see the TreeConnect call,
6483                            store this TID here as well as a IPC TID 
6484                            so we know that future Read/Writes to this 
6485                            TID is (probably) DCERPC.
6486                         */
6487                         if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
6488                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6489                         }
6490                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6491                 }
6492                 if(si->sip){
6493                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
6494                 }
6495         }
6496
6497         /* file data, might be DCERPC on a pipe */
6498         if (bc != 0) {
6499                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6500                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6501                 bc = 0;
6502         }
6503
6504         END_OF_SMB
6505
6506         if (cmd != 0xff) {      /* there is an andX command */
6507                 if (andxoffset < offset)
6508                         THROW(ReportedBoundsError);
6509                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6510         }
6511
6512         return offset;
6513 }
6514
6515 static int
6516 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6517 {
6518         guint8  wc, cmd=0xff;
6519         guint16 andxoffset=0, bc, count_low, count_high;
6520         guint32 count=0;
6521         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6522         rw_info_t *rwi=NULL;
6523
6524         DISSECTOR_ASSERT(si);
6525
6526         WORD_COUNT;
6527
6528         /* next smb command */
6529         cmd = tvb_get_guint8(tvb, offset);
6530         if(cmd!=0xff){
6531                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6532         } else {
6533                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6534         }
6535         offset += 1;
6536
6537         /* reserved byte */
6538         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6539         offset += 1;
6540
6541         /* andxoffset */
6542         andxoffset = tvb_get_letohs(tvb, offset);
6543         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6544         offset += 2;
6545
6546
6547         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6548                 rwi=si->sip->extra_info;
6549         }
6550         if(rwi){
6551                 proto_item *it;
6552
6553                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6554
6555                 PROTO_ITEM_SET_GENERATED(it);
6556                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6557                 PROTO_ITEM_SET_GENERATED(it);
6558         }
6559
6560
6561         /* write count low */
6562         count_low = tvb_get_letohs(tvb, offset);
6563         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6564         offset += 2;
6565
6566         /* remaining */
6567         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6568         offset += 2;
6569
6570         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6571         /* write count high */
6572         count_high = tvb_get_letohs(tvb, offset);
6573         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6574         offset += 2;
6575
6576         count=count_high;
6577         count=(count<<16)|count_low;
6578
6579         if (check_col(pinfo->cinfo, COL_INFO))
6580                 col_append_fstr(pinfo->cinfo, COL_INFO,
6581                                 ", %u byte%s", count,
6582                                 (count == 1) ? "" : "s");
6583
6584         /* 2 reserved bytes */
6585         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6586         offset += 2;
6587
6588         BYTE_COUNT;
6589
6590         END_OF_SMB
6591
6592         if (cmd != 0xff) {      /* there is an andX command */
6593                 if (andxoffset < offset)
6594                         THROW(ReportedBoundsError);
6595                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6596         }
6597
6598         return offset;
6599 }
6600
6601
6602 static const true_false_string tfs_setup_action_guest = {
6603         "Logged in as GUEST",
6604         "Not logged in as GUEST"
6605 };
6606 static int
6607 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6608 {
6609         guint16 mask;
6610         proto_item *item = NULL;
6611         proto_tree *tree = NULL;
6612
6613         mask = tvb_get_letohs(tvb, offset);
6614
6615         if(parent_tree){
6616                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6617                         "Action: 0x%04x", mask);
6618                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
6619         }
6620
6621         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
6622                 tvb, offset, 2, mask);
6623
6624         offset += 2;
6625
6626         return offset;
6627 }
6628
6629
6630 static int
6631 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6632 {
6633         guint8  wc, cmd=0xff;
6634         guint16 bc;
6635         guint16 andxoffset=0;
6636         smb_info_t *si = pinfo->private_data;
6637         int an_len;
6638         const char *an;
6639         int dn_len;
6640         const char *dn;
6641         guint16 pwlen=0;
6642         guint16 sbloblen=0, sbloblen_short;
6643         guint16 apwlen=0, upwlen=0;
6644         gboolean unicodeflag;
6645         static int ntlmssp_tap_id = 0;
6646         const ntlmssp_header_t *ntlmssph;
6647
6648         if(!ntlmssp_tap_id){
6649                 GString *error_string;
6650                 /* We dont specify any callbacks at all.
6651                  * Instead we manually fetch the tapped data after the
6652                  * security blob has been fully dissected and before
6653                  * we exit from this dissector.
6654                  */
6655                 error_string=register_tap_listener("ntlmssp", NULL, NULL, NULL, NULL, NULL);
6656                 if(!error_string){
6657                         ntlmssp_tap_id=find_tap_id("ntlmssp");
6658                 }
6659         }
6660
6661         DISSECTOR_ASSERT(si);
6662
6663         WORD_COUNT;
6664
6665         /* next smb command */
6666         cmd = tvb_get_guint8(tvb, offset);
6667         if(cmd!=0xff){
6668                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6669         } else {
6670                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6671         }
6672         offset += 1;
6673
6674         /* reserved byte */
6675         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6676         offset += 1;
6677
6678         /* andxoffset */
6679         andxoffset = tvb_get_letohs(tvb, offset);
6680         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6681         offset += 2;
6682
6683         /* Maximum Buffer Size */
6684         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
6685         offset += 2;
6686
6687         /* Maximum Multiplex Count */
6688         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
6689         offset += 2;
6690
6691         /* VC Number */
6692         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
6693         offset += 2;
6694
6695         /* session key */
6696         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
6697         offset += 4;
6698
6699         switch (wc) {
6700         case 10:
6701                 /* password length, ASCII*/
6702                 pwlen = tvb_get_letohs(tvb, offset);
6703                 proto_tree_add_uint(tree, hf_smb_password_len,
6704                         tvb, offset, 2, pwlen);
6705                 offset += 2;
6706
6707                 /* 4 reserved bytes */
6708                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6709                 offset += 4;
6710
6711                 break;
6712
6713         case 12:
6714                 /* security blob length */
6715                 sbloblen = tvb_get_letohs(tvb, offset);
6716                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6717                 offset += 2;
6718
6719                 /* 4 reserved bytes */
6720                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6721                 offset += 4;
6722
6723                 /* capabilities */
6724                 dissect_negprot_capabilities(tvb, tree, offset);
6725                 offset += 4;
6726
6727                 break;
6728
6729         case 13:
6730                 /* password length, ANSI*/
6731                 apwlen = tvb_get_letohs(tvb, offset);
6732                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
6733                         tvb, offset, 2, apwlen);
6734                 offset += 2;
6735
6736                 /* password length, Unicode*/
6737                 upwlen = tvb_get_letohs(tvb, offset);
6738                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
6739                         tvb, offset, 2, upwlen);
6740                 offset += 2;
6741
6742                 /* 4 reserved bytes */
6743                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6744                 offset += 4;
6745
6746                 /* capabilities */
6747                 dissect_negprot_capabilities(tvb, tree, offset);
6748                 offset += 4;
6749
6750                 break;
6751         }
6752
6753         BYTE_COUNT;
6754
6755         if (wc==12) {
6756                 proto_item *blob_item;
6757
6758                 /* security blob */
6759                 /* If it runs past the end of the captured data, don't
6760                  * try to put all of it into the protocol tree as the
6761                  * raw security blob; we might get an exception on 
6762                  * short frames and then we will not see anything at all
6763                  * of the security blob.
6764                  */
6765                 sbloblen_short = sbloblen;
6766                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
6767                         sbloblen_short=tvb_length_remaining(tvb,offset);
6768                 }
6769                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6770                                                 tvb, offset, sbloblen_short,
6771                                                 TRUE);
6772
6773                 /* As an optimization, because Windows is perverse,
6774                    we check to see if NTLMSSP is the first part of the 
6775                    blob, and if so, call the NTLMSSP dissector,
6776                    otherwise we call the GSS-API dissector. This is because
6777                    Windows can request RAW NTLMSSP, but will happily handle
6778                    a client that wraps NTLMSSP in SPNEGO
6779                 */
6780
6781                 if(sbloblen){
6782                         tvbuff_t *blob_tvb;
6783                         proto_tree *blob_tree;
6784
6785                         blob_tree = proto_item_add_subtree(blob_item, 
6786                                                            ett_smb_secblob);
6787                         CHECK_BYTE_COUNT(sbloblen);
6788
6789                         /*
6790                          * Set the reported length of this to the reported
6791                          * length of the blob, rather than the amount of
6792                          * data available from the blob, so that we'll
6793                          * throw the right exception if it's too short.
6794                          */
6795                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
6796                                                   sbloblen);
6797
6798                         if (si && si->ct && si->ct->raw_ntlmssp &&
6799                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6800                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6801                                          blob_tree);
6802
6803                         }
6804                         else {
6805                           call_dissector(gssapi_handle, blob_tvb, 
6806                                          pinfo, blob_tree);
6807                         }
6808
6809                         /* If we have found a uid->acct_name mapping, store it */
6810                         if(!pinfo->fd->flags.visited && si->sip){
6811                                 int idx=0;
6812                                 if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
6813                                         if(ntlmssph && ntlmssph->type==3){
6814                                                 smb_uid_t *smb_uid;
6815         
6816                                                 smb_uid=se_alloc(sizeof(smb_uid_t));
6817                                                 smb_uid->logged_in=-1;
6818                                                 smb_uid->logged_out=-1;
6819                                                 smb_uid->domain=se_strdup(ntlmssph->domain_name);
6820                                                 smb_uid->account=se_strdup(ntlmssph->acct_name);
6821
6822                                                 si->sip->extra_info=smb_uid;
6823                                                 si->sip->extra_info_type=SMB_EI_UID;
6824                                         }
6825                                 }
6826                         }
6827
6828                         COUNT_BYTES(sbloblen);
6829                 }
6830
6831                 /* OS
6832                  * Eventhough this field should honour the unicode flag
6833                  * some ms clients gets this wrong.
6834                  * At least XP SP1 sends this in ASCII
6835                  * even when the unicode flag is on.
6836                  * Test if the first three bytes are "Win"
6837                  * and if so just override the flag.
6838                  */
6839                 unicodeflag=si->unicode;
6840                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6841                         unicodeflag=FALSE;
6842                 }
6843                 an = get_unicode_or_ascii_string(tvb, &offset,
6844                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6845                 if (an == NULL)
6846                         goto endofcommand;
6847                 proto_tree_add_string(tree, hf_smb_os, tvb,
6848                         offset, an_len, an);
6849                 COUNT_BYTES(an_len);
6850
6851                 /* LANMAN */
6852                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6853                  * padding/null string/whatever in front of this. W2K doesn't
6854                  * appear to. I suspect that's a bug that got fixed; I also
6855                  * suspect that, in practice, nobody ever looks at that field
6856                  * because the bug didn't appear to get fixed until NT 5.0....
6857                  *
6858                  * Eventhough this field should honour the unicode flag
6859                  * some ms clients gets this wrong.
6860                  * At least XP SP1 sends this in ASCII
6861                  * even when the unicode flag is on.
6862                  * Test if the first three bytes are "Win"
6863                  * and if so just override the flag.
6864                  */
6865                 unicodeflag=si->unicode;
6866                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6867                         unicodeflag=FALSE;
6868                 }
6869                 an = get_unicode_or_ascii_string(tvb, &offset,
6870                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6871                 if (an == NULL)
6872                         goto endofcommand;
6873                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6874                         offset, an_len, an);
6875                 COUNT_BYTES(an_len);
6876
6877                 /* Primary domain */
6878                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6879                  * byte in front of this, at least if all the strings are
6880                  * ASCII and the account name is empty. Another bug?
6881                  */
6882                 dn = get_unicode_or_ascii_string(tvb, &offset,
6883                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6884                 if (dn == NULL)
6885                         goto endofcommand;
6886                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6887                         offset, dn_len, dn);
6888                 COUNT_BYTES(dn_len);
6889         } else {
6890                 switch (wc) {
6891
6892                 case 10:
6893                         if(pwlen){
6894                                 /* password, ASCII */
6895                                 CHECK_BYTE_COUNT(pwlen);
6896                                 proto_tree_add_item(tree, hf_smb_password,
6897                                         tvb, offset, pwlen, TRUE);
6898                                 COUNT_BYTES(pwlen);
6899                         }
6900
6901                         break;
6902
6903                 case 13:
6904                         if(apwlen){
6905                                 /* password, ANSI */
6906                                 CHECK_BYTE_COUNT(apwlen);
6907                                 proto_tree_add_item(tree, hf_smb_ansi_password,
6908                                         tvb, offset, apwlen, TRUE);
6909                                 COUNT_BYTES(apwlen);
6910                         }
6911
6912                         if(upwlen){
6913                                 proto_item *item;
6914
6915                                 /* password, Unicode */
6916                                 CHECK_BYTE_COUNT(upwlen);
6917                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
6918                                         tvb, offset, upwlen, TRUE);
6919
6920                                 if (upwlen > 24) {
6921                                         proto_tree *subtree;
6922
6923                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
6924
6925                                         dissect_ntlmv2_response(
6926                                                 tvb, subtree, offset, upwlen);
6927                                 }
6928
6929                                 COUNT_BYTES(upwlen);
6930                         }
6931
6932                         break;
6933                 }
6934
6935                 /* Account Name */
6936                 an = get_unicode_or_ascii_string(tvb, &offset,
6937                         si->unicode, &an_len, FALSE, FALSE, &bc);
6938                 if (an == NULL)
6939                         goto endofcommand;
6940                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
6941                         an);
6942                 COUNT_BYTES(an_len);
6943
6944                 /* Primary domain */
6945                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6946                  * byte in front of this, at least if all the strings are
6947                  * ASCII and the account name is empty. Another bug?
6948                  */
6949                 dn = get_unicode_or_ascii_string(tvb, &offset,
6950                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6951                 if (dn == NULL)
6952                         goto endofcommand;
6953                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6954                         offset, dn_len, dn);
6955                 COUNT_BYTES(dn_len);
6956
6957                 if (check_col(pinfo->cinfo, COL_INFO)) {
6958                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
6959
6960                         if (!dn[0] && !an[0])
6961                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6962                                                 "anonymous");
6963                         else
6964                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6965                                                 "%s\\%s",
6966                                                 format_text(dn, strlen(dn)),
6967                                                 format_text(an, strlen(an)));
6968                 }
6969
6970                 /* OS */
6971                 an = get_unicode_or_ascii_string(tvb, &offset,
6972                         si->unicode, &an_len, FALSE, FALSE, &bc);
6973                 if (an == NULL)
6974                         goto endofcommand;
6975                 proto_tree_add_string(tree, hf_smb_os, tvb,
6976                         offset, an_len, an);
6977                 COUNT_BYTES(an_len);
6978
6979                 /* LANMAN */
6980                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6981                  * padding/null string/whatever in front of this. W2K doesn't
6982                  * appear to. I suspect that's a bug that got fixed; I also
6983                  * suspect that, in practice, nobody ever looks at that field
6984                  * because the bug didn't appear to get fixed until NT 5.0....
6985                  */
6986                 an = get_unicode_or_ascii_string(tvb, &offset,
6987                         si->unicode, &an_len, FALSE, FALSE, &bc);
6988                 if (an == NULL)
6989                         goto endofcommand;
6990                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6991                         offset, an_len, an);
6992                 COUNT_BYTES(an_len);
6993         }
6994
6995         END_OF_SMB
6996
6997         if (cmd != 0xff) {      /* there is an andX command */
6998                 if (andxoffset < offset)
6999                         THROW(ReportedBoundsError);
7000                 pinfo->private_data = si;
7001                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7002         }
7003
7004         return offset;
7005 }
7006
7007 static int
7008 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7009 {
7010         guint8  wc, cmd=0xff;
7011         guint16 andxoffset=0, bc;
7012         guint16 sbloblen=0;
7013         smb_info_t *si = pinfo->private_data;
7014         int an_len;
7015         const char *an;
7016
7017         DISSECTOR_ASSERT(si);
7018
7019         WORD_COUNT;
7020
7021         if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7022             si->sip->extra_info_type==SMB_EI_UID){
7023                 smb_uid_t *smb_uid;
7024
7025                 smb_uid=si->sip->extra_info;
7026                 smb_uid->logged_in=pinfo->fd->num;
7027                 se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7028         }
7029
7030         /* next smb command */
7031         cmd = tvb_get_guint8(tvb, offset);
7032         if(cmd!=0xff){
7033                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7034         } else {
7035                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7036         }
7037         offset += 1;
7038
7039         /* reserved byte */
7040         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7041         offset += 1;
7042
7043         /* andxoffset */
7044         andxoffset = tvb_get_letohs(tvb, offset);
7045         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7046         offset += 2;
7047
7048         /* flags */
7049         offset = dissect_setup_action(tvb, tree, offset);
7050
7051         if(wc==4){
7052                 /* security blob length */
7053                 sbloblen = tvb_get_letohs(tvb, offset);
7054                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7055                 offset += 2;
7056         }
7057
7058         BYTE_COUNT;
7059
7060         if(wc==4) {
7061                 proto_item *blob_item;
7062
7063                 /* security blob */
7064                 /* dont try to eat too much of we might get an exception on 
7065                  * short frames and then we will not see anything at all
7066                  * of the security blob.
7067                  */
7068                 if(sbloblen>tvb_length_remaining(tvb,offset)){
7069                         sbloblen=tvb_length_remaining(tvb,offset);
7070                 }
7071                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7072                                                 tvb, offset, sbloblen, TRUE);
7073
7074                 if(sbloblen){
7075                         tvbuff_t *blob_tvb;
7076                         proto_tree *blob_tree;
7077
7078                         blob_tree = proto_item_add_subtree(blob_item, 
7079                                                            ett_smb_secblob);
7080                         CHECK_BYTE_COUNT(sbloblen);
7081
7082                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
7083                                                     sbloblen);
7084
7085                         if (si && si->ct && si->ct->raw_ntlmssp && 
7086                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
7087                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7088                                          blob_tree);
7089
7090                         }
7091                         else {
7092                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
7093                                          blob_tree);
7094
7095                         }
7096
7097                         COUNT_BYTES(sbloblen);
7098                 }
7099         }
7100
7101         /* OS */
7102         an = get_unicode_or_ascii_string(tvb, &offset,
7103                 si->unicode, &an_len, FALSE, FALSE, &bc);
7104         if (an == NULL)
7105                 goto endofcommand;
7106         proto_tree_add_string(tree, hf_smb_os, tvb,
7107                 offset, an_len, an);
7108         COUNT_BYTES(an_len);
7109
7110         /* LANMAN */
7111         an = get_unicode_or_ascii_string(tvb, &offset,
7112                 si->unicode, &an_len, FALSE, FALSE, &bc);
7113         if (an == NULL)
7114                 goto endofcommand;
7115         proto_tree_add_string(tree, hf_smb_lanman, tvb,
7116                 offset, an_len, an);
7117         COUNT_BYTES(an_len);
7118
7119         if((wc==3)||(wc==4)) {
7120                 /* Primary domain */
7121                 an = get_unicode_or_ascii_string(tvb, &offset,
7122                         si->unicode, &an_len, FALSE, FALSE, &bc);
7123                 if (an == NULL)
7124                         goto endofcommand;
7125                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7126                         offset, an_len, an);
7127                 COUNT_BYTES(an_len);
7128         }
7129
7130         END_OF_SMB
7131
7132         if (cmd != 0xff) {      /* there is an andX command */
7133                 if (andxoffset < offset)
7134                         THROW(ReportedBoundsError);
7135                 pinfo->private_data = si;
7136                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7137         }
7138
7139         return offset;
7140 }
7141
7142
7143 static int
7144 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7145 {
7146         guint8  wc, cmd=0xff;
7147         guint16 andxoffset=0;
7148         guint16 bc;
7149
7150         WORD_COUNT;
7151
7152         /* next smb command */
7153         cmd = tvb_get_guint8(tvb, offset);
7154         if(cmd!=0xff){
7155                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7156         } else {
7157                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7158         }
7159         offset += 1;
7160
7161         /* reserved byte */
7162         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7163         offset += 1;
7164
7165         /* andxoffset */
7166         andxoffset = tvb_get_letohs(tvb, offset);
7167         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7168         offset += 2;
7169
7170         BYTE_COUNT;
7171
7172         END_OF_SMB
7173
7174         if (cmd != 0xff) {      /* there is an andX command */
7175                 if (andxoffset < offset)
7176                         THROW(ReportedBoundsError);
7177                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7178         }
7179
7180         return offset;
7181 }
7182
7183
7184 static const true_false_string tfs_connect_support_search = {
7185         "Exclusive search bits supported",
7186         "Exclusive search bits not supported"
7187 };
7188 static const true_false_string tfs_connect_support_in_dfs = {
7189         "Share is in Dfs",
7190         "Share isn't in Dfs"
7191 };
7192
7193 static int
7194 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7195 {
7196         guint16 mask;
7197         proto_item *item = NULL;
7198         proto_tree *tree = NULL;
7199
7200         mask = tvb_get_letohs(tvb, offset);
7201
7202         if(parent_tree){
7203                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7204                         "Optional Support: 0x%04x", mask);
7205                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7206         }
7207
7208         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7209                 tvb, offset, 2, mask);
7210         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7211                 tvb, offset, 2, mask);
7212
7213         offset += 2;
7214
7215         return offset;
7216 }
7217
7218 static const true_false_string tfs_disconnect_tid = {
7219         "DISCONNECT TID",
7220         "Do NOT disconnect TID"
7221 };
7222
7223 static int
7224 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7225 {
7226         guint16 mask;
7227         proto_item *item = NULL;
7228         proto_tree *tree = NULL;
7229
7230         mask = tvb_get_letohs(tvb, offset);
7231
7232         if(parent_tree){
7233                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7234                         "Flags: 0x%04x", mask);
7235                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7236         }
7237
7238         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7239                 tvb, offset, 2, mask);
7240
7241         offset += 2;
7242
7243         return offset;
7244 }
7245
7246 static int
7247 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7248 {
7249         guint8  wc, cmd=0xff;
7250         guint16 bc;
7251         guint16 andxoffset=0, pwlen=0;
7252         smb_info_t *si = pinfo->private_data;
7253         int an_len;
7254         const char *an;
7255
7256         DISSECTOR_ASSERT(si);
7257
7258         WORD_COUNT;
7259
7260         /* next smb command */
7261         cmd = tvb_get_guint8(tvb, offset);
7262         if(cmd!=0xff){
7263                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7264         } else {
7265                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7266         }
7267         offset += 1;
7268
7269         /* reserved byte */
7270         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7271         offset += 1;
7272
7273         /* andxoffset */
7274         andxoffset = tvb_get_letohs(tvb, offset);
7275         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7276         offset += 2;
7277
7278         /* flags */
7279         offset = dissect_connect_flags(tvb, tree, offset);
7280
7281         /* password length*/
7282         pwlen = tvb_get_letohs(tvb, offset);
7283         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7284         offset += 2;
7285
7286         BYTE_COUNT;
7287
7288         /* password */
7289         CHECK_BYTE_COUNT(pwlen);
7290         proto_tree_add_item(tree, hf_smb_password,
7291                 tvb, offset, pwlen, TRUE);
7292         COUNT_BYTES(pwlen);
7293
7294         /* Path */
7295         an = get_unicode_or_ascii_string(tvb, &offset,
7296                 si->unicode, &an_len, FALSE, FALSE, &bc);
7297         if (an == NULL)
7298                 goto endofcommand;
7299         proto_tree_add_string(tree, hf_smb_path, tvb,
7300                 offset, an_len, an);
7301         COUNT_BYTES(an_len);
7302
7303         /* store it for the tid->name/openframe/closeframe matching in
7304          * dissect_smb_tid()   called from the response.
7305          */
7306         if((!pinfo->fd->flags.visited) && si->sip && an){
7307                 si->sip->extra_info_type=SMB_EI_TIDNAME;
7308                 si->sip->extra_info=se_strdup(an);
7309         }
7310
7311         if (check_col(pinfo->cinfo, COL_INFO)) {
7312                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7313                     format_text(an, strlen(an)));
7314         }
7315
7316         /*
7317          * NOTE: the Service string is always ASCII, even if the
7318          * "strings are Unicode" bit is set in the flags2 field
7319          * of the SMB.
7320          */
7321
7322         /* Service */
7323         /* XXX - what if this runs past bc? */
7324         an_len = tvb_strsize(tvb, offset);
7325         CHECK_BYTE_COUNT(an_len);
7326         an = tvb_get_ptr(tvb, offset, an_len);
7327         proto_tree_add_string(tree, hf_smb_service, tvb,
7328                 offset, an_len, an);
7329         COUNT_BYTES(an_len);
7330
7331         END_OF_SMB
7332
7333         if (cmd != 0xff) {      /* there is an andX command */
7334                 if (andxoffset < offset)
7335                         THROW(ReportedBoundsError);
7336                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7337         }
7338
7339         return offset;
7340 }
7341
7342
7343 static int
7344 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7345 {
7346         guint8  wc, wleft, cmd=0xff;
7347         guint16 andxoffset=0;
7348         guint16 bc;
7349         int an_len;
7350         const char *an;
7351         smb_info_t *si = pinfo->private_data;
7352
7353         DISSECTOR_ASSERT(si);
7354
7355         WORD_COUNT;
7356
7357         wleft = wc;     /* this is at least 1 */
7358
7359         /* next smb command */
7360         cmd = tvb_get_guint8(tvb, offset);
7361         if(cmd!=0xff){
7362                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7363         } else {
7364                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7365         }
7366         offset += 1;
7367
7368         /* reserved byte */
7369         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7370         offset += 1;
7371
7372         wleft--;
7373         if (wleft == 0)
7374                 goto bytecount;
7375
7376         /* andxoffset */
7377         andxoffset = tvb_get_letohs(tvb, offset);
7378         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7379         offset += 2;
7380         wleft--;
7381         if (wleft == 0)
7382                 goto bytecount;
7383
7384         /* flags */
7385         offset = dissect_connect_support_bits(tvb, tree, offset);
7386         wleft--;
7387
7388         /* XXX - I've seen captures where this is 7, but I have no
7389            idea how to dissect it.  I'm guessing the third word
7390            contains connect support bits, which looks plausible
7391            from the values I've seen. */
7392
7393         while (wleft != 0) {
7394                 proto_tree_add_text(tree, tvb, offset, 2,
7395                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
7396                 offset += 2;
7397                 wleft--;
7398         }
7399
7400         BYTE_COUNT;
7401
7402         /*
7403          * NOTE: even though the SNIA CIFS spec doesn't say there's
7404          * a "Service" string if there's a word count of 2, the
7405          * document at
7406          *
7407          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7408          *
7409          * (it's in an ugly format - text intended to be sent to a
7410          * printer, with backspaces and overstrikes used for boldfacing
7411          * and underlining; UNIX "col -b" can be used to strip the
7412          * overstrikes out) says there's a "Service" string there, and
7413          * some network traffic has it.
7414          */
7415
7416         /*
7417          * NOTE: the Service string is always ASCII, even if the
7418          * "strings are Unicode" bit is set in the flags2 field
7419          * of the SMB.
7420          */
7421
7422         /* Service */
7423         /* XXX - what if this runs past bc? */
7424         an_len = tvb_strsize(tvb, offset);
7425         CHECK_BYTE_COUNT(an_len);
7426         an = tvb_get_ptr(tvb, offset, an_len);
7427         proto_tree_add_string(tree, hf_smb_service, tvb,
7428                 offset, an_len, an);
7429         COUNT_BYTES(an_len);
7430
7431         /* Now when we know the service type, store it so that we know it for later commands down
7432            this tree */
7433         if(!pinfo->fd->flags.visited){
7434                 /* Remove any previous entry for this TID */
7435                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
7436                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7437                 }
7438                 if(strcmp(an,"IPC") == 0){
7439                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7440                 } else {
7441                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7442                 }
7443         }
7444
7445
7446         if(wc==3){
7447                 if (bc != 0) {
7448                         /*
7449                          * Sometimes this isn't present.
7450                          */
7451
7452                         /* Native FS */
7453                         an = get_unicode_or_ascii_string(tvb, &offset,
7454                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7455                                 &bc);
7456                         if (an == NULL)
7457                                 goto endofcommand;
7458                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7459                                 offset, an_len, an);
7460                         COUNT_BYTES(an_len);
7461                 }
7462         }
7463
7464         END_OF_SMB
7465
7466         if (cmd != 0xff) {      /* there is an andX command */
7467                 if (andxoffset < offset)
7468                         THROW(ReportedBoundsError);
7469                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7470         }
7471
7472         return offset;
7473 }
7474
7475
7476
7477 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7478    NT Transaction command  begins here
7479    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7480 #define NT_TRANS_CREATE         1
7481 #define NT_TRANS_IOCTL          2
7482 #define NT_TRANS_SSD            3
7483 #define NT_TRANS_NOTIFY         4
7484 #define NT_TRANS_RENAME         5
7485 #define NT_TRANS_QSD            6
7486 #define NT_TRANS_GET_USER_QUOTA 7
7487 #define NT_TRANS_SET_USER_QUOTA 8
7488 const value_string nt_cmd_vals[] = {
7489         {NT_TRANS_CREATE,               "NT CREATE"},
7490         {NT_TRANS_IOCTL,                "NT IOCTL"},
7491         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7492         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7493         {NT_TRANS_RENAME,               "NT RENAME"},
7494         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7495         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7496         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7497         {0, NULL}
7498 };
7499
7500 static const value_string nt_ioctl_isfsctl_vals[] = {
7501         {0,     "Device IOCTL"},
7502         {1,     "FS control : FSCTL"},
7503         {0, NULL}
7504 };
7505
7506 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7507 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7508         "Apply the command to share root handle (MUST BE Dfs)",
7509         "Apply to this share",
7510 };
7511
7512 static const value_string nt_notify_action_vals[] = {
7513         {1,     "ADDED (object was added"},
7514         {2,     "REMOVED (object was removed)"},
7515         {3,     "MODIFIED (object was modified)"},
7516         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7517         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7518         {6,     "ADDED_STREAM (a stream was added)"},
7519         {7,     "REMOVED_STREAM (a stream was removed)"},
7520         {8,     "MODIFIED_STREAM (a stream was modified)"},
7521         {0, NULL}
7522 };
7523
7524 static const value_string watch_tree_vals[] = {
7525         {0,     "Current directory only"},
7526         {1,     "Subdirectories also"},
7527         {0, NULL}
7528 };
7529
7530 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7531 #define NT_NOTIFY_STREAM_SIZE   0x00000400
7532 #define NT_NOTIFY_STREAM_NAME   0x00000200
7533 #define NT_NOTIFY_SECURITY      0x00000100
7534 #define NT_NOTIFY_EA            0x00000080
7535 #define NT_NOTIFY_CREATION      0x00000040
7536 #define NT_NOTIFY_LAST_ACCESS   0x00000020
7537 #define NT_NOTIFY_LAST_WRITE    0x00000010
7538 #define NT_NOTIFY_SIZE          0x00000008
7539 #define NT_NOTIFY_ATTRIBUTES    0x00000004
7540 #define NT_NOTIFY_DIR_NAME      0x00000002
7541 #define NT_NOTIFY_FILE_NAME     0x00000001
7542 static const true_false_string tfs_nt_notify_stream_write = {
7543         "Notify on changes to STREAM WRITE",
7544         "Do NOT notify on changes to stream write",
7545 };
7546 static const true_false_string tfs_nt_notify_stream_size = {
7547         "Notify on changes to STREAM SIZE",
7548         "Do NOT notify on changes to stream size",
7549 };
7550 static const true_false_string tfs_nt_notify_stream_name = {
7551         "Notify on changes to STREAM NAME",
7552         "Do NOT notify on changes to stream name",
7553 };
7554 static const true_false_string tfs_nt_notify_security = {
7555         "Notify on changes to SECURITY",
7556         "Do NOT notify on changes to security",
7557 };
7558 static const true_false_string tfs_nt_notify_ea = {
7559         "Notify on changes to EA",
7560         "Do NOT notify on changes to EA",
7561 };
7562 static const true_false_string tfs_nt_notify_creation = {
7563         "Notify on changes to CREATION TIME",
7564         "Do NOT notify on changes to creation time",
7565 };
7566 static const true_false_string tfs_nt_notify_last_access = {
7567         "Notify on changes to LAST ACCESS TIME",
7568         "Do NOT notify on changes to last access time",
7569 };
7570 static const true_false_string tfs_nt_notify_last_write = {
7571         "Notify on changes to LAST WRITE TIME",
7572         "Do NOT notify on changes to last write time",
7573 };
7574 static const true_false_string tfs_nt_notify_size = {
7575         "Notify on changes to SIZE",
7576         "Do NOT notify on changes to size",
7577 };
7578 static const true_false_string tfs_nt_notify_attributes = {
7579         "Notify on changes to ATTRIBUTES",
7580         "Do NOT notify on changes to attributes",
7581 };
7582 static const true_false_string tfs_nt_notify_dir_name = {
7583         "Notify on changes to DIR NAME",
7584         "Do NOT notify on changes to dir name",
7585 };
7586 static const true_false_string tfs_nt_notify_file_name = {
7587         "Notify on changes to FILE NAME",
7588         "Do NOT notify on changes to file name",
7589 };
7590
7591 const value_string create_disposition_vals[] = {
7592         {0,     "Supersede (supersede existing file (if it exists))"},
7593         {1,     "Open (if file exists open it, else fail)"},
7594         {2,     "Create (if file exists fail, else create it)"},
7595         {3,     "Open If (if file exists open it, else create it)"},
7596         {4,     "Overwrite (if file exists overwrite, else fail)"},
7597         {5,     "Overwrite If (if file exists overwrite, else create it)"},
7598         {0, NULL}
7599 };
7600
7601 const value_string impersonation_level_vals[] = {
7602         {0,     "Anonymous"},
7603         {1,     "Identification"},
7604         {2,     "Impersonation"},
7605         {3,     "Delegation"},
7606         {0, NULL}
7607 };
7608
7609 static const true_false_string tfs_nt_security_flags_context_tracking = {
7610         "Security tracking mode is DYNAMIC",
7611         "Security tracking mode is STATIC",
7612 };
7613
7614 static const true_false_string tfs_nt_security_flags_effective_only = {
7615         "ONLY ENABLED aspects of the client's security context are available",
7616         "ALL aspects of the client's security context are available",
7617 };
7618
7619 static const true_false_string tfs_nt_create_bits_oplock = {
7620         "Requesting OPLOCK",
7621         "Does NOT request oplock"
7622 };
7623
7624 static const true_false_string tfs_nt_create_bits_boplock = {
7625         "Requesting BATCH OPLOCK",
7626         "Does NOT request batch oplock"
7627 };
7628
7629 /*
7630  * XXX - must be a directory, and can be a file, or can be a directory,
7631  * and must be a file?
7632  */
7633 static const true_false_string tfs_nt_create_bits_dir = {
7634         "Target of open MUST be a DIRECTORY",
7635         "Target of open can be a file"
7636 };
7637
7638 static const true_false_string tfs_nt_create_bits_ext_resp = {
7639   "Extended responses required",
7640   "Extended responses NOT required"
7641 };
7642
7643 static const true_false_string tfs_nt_access_mask_generic_read = {
7644         "GENERIC READ is set",
7645         "Generic read is NOT set"
7646 };
7647 static const true_false_string tfs_nt_access_mask_generic_write = {
7648         "GENERIC WRITE is set",
7649         "Generic write is NOT set"
7650 };
7651 static const true_false_string tfs_nt_access_mask_generic_execute = {
7652         "GENERIC EXECUTE is set",
7653         "Generic execute is NOT set"
7654 };
7655 static const true_false_string tfs_nt_access_mask_generic_all = {
7656         "GENERIC ALL is set",
7657         "Generic all is NOT set"
7658 };
7659 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
7660         "MAXIMUM ALLOWED is set",
7661         "Maximum allowed is NOT set"
7662 };
7663 static const true_false_string tfs_nt_access_mask_system_security = {
7664         "SYSTEM SECURITY is set",
7665         "System security is NOT set"
7666 };
7667 static const true_false_string tfs_nt_access_mask_synchronize = {
7668         "Can wait on handle to SYNCHRONIZE on completion of I/O",
7669         "Can NOT wait on handle to synchronize on completion of I/O"
7670 };
7671 static const true_false_string tfs_nt_access_mask_write_owner = {
7672         "Can WRITE OWNER (take ownership)",
7673         "Can NOT write owner (take ownership)"
7674 };
7675 static const true_false_string tfs_nt_access_mask_write_dac = {
7676         "OWNER may WRITE the DAC",
7677         "Owner may NOT write to the DAC"
7678 };
7679 static const true_false_string tfs_nt_access_mask_read_control = {
7680         "READ ACCESS to owner, group and ACL of the SID",
7681         "Read access is NOT granted to owner, group and ACL of the SID"
7682 };
7683 static const true_false_string tfs_nt_access_mask_delete = {
7684         "DELETE access",
7685         "NO delete access"
7686 };
7687 static const true_false_string tfs_nt_access_mask_write_attributes = {
7688         "WRITE ATTRIBUTES access",
7689         "NO write attributes access"
7690 };
7691 static const true_false_string tfs_nt_access_mask_read_attributes = {
7692         "READ ATTRIBUTES access",
7693         "NO read attributes access"
7694 };
7695 static const true_false_string tfs_nt_access_mask_delete_child = {
7696         "DELETE CHILD access",
7697         "NO delete child access"
7698 };
7699 static const true_false_string tfs_nt_access_mask_execute = {
7700         "EXECUTE access",
7701         "NO execute access"
7702 };
7703 static const true_false_string tfs_nt_access_mask_write_ea = {
7704         "WRITE EXTENDED ATTRIBUTES access",
7705         "NO write extended attributes access"
7706 };
7707 static const true_false_string tfs_nt_access_mask_read_ea = {
7708         "READ EXTENDED ATTRIBUTES access",
7709         "NO read extended attributes access"
7710 };
7711 static const true_false_string tfs_nt_access_mask_append = {
7712         "APPEND access",
7713         "NO append access"
7714 };
7715 static const true_false_string tfs_nt_access_mask_write = {
7716         "WRITE access",
7717         "NO write access"
7718 };
7719 static const true_false_string tfs_nt_access_mask_read = {
7720         "READ access",
7721         "NO read access"
7722 };
7723
7724 static const true_false_string tfs_nt_share_access_delete = {
7725         "Object can be shared for DELETE",
7726         "Object can NOT be shared for delete"
7727 };
7728 static const true_false_string tfs_nt_share_access_write = {
7729         "Object can be shared for WRITE",
7730         "Object can NOT be shared for write"
7731 };
7732 static const true_false_string tfs_nt_share_access_read = {
7733         "Object can be shared for READ",
7734         "Object can NOT be shared for read"
7735 };
7736
7737 static const value_string oplock_level_vals[] = {
7738         {0,     "No oplock granted"},
7739         {1,     "Exclusive oplock granted"},
7740         {2,     "Batch oplock granted"},
7741         {3,     "Level II oplock granted"},
7742         {0, NULL}
7743 };
7744
7745 static const value_string device_type_vals[] = {
7746         {0x00000001,    "Beep"},
7747         {0x00000002,    "CDROM"},
7748         {0x00000003,    "CDROM Filesystem"},
7749         {0x00000004,    "Controller"},
7750         {0x00000005,    "Datalink"},
7751         {0x00000006,    "Dfs"},
7752         {0x00000007,    "Disk"},
7753         {0x00000008,    "Disk Filesystem"},
7754         {0x00000009,    "Filesystem"},
7755         {0x0000000a,    "Inport Port"},
7756         {0x0000000b,    "Keyboard"},
7757         {0x0000000c,    "Mailslot"},
7758         {0x0000000d,    "MIDI-In"},
7759         {0x0000000e,    "MIDI-Out"},
7760         {0x0000000f,    "Mouse"},
7761         {0x00000010,    "Multi UNC Provider"},
7762         {0x00000011,    "Named Pipe"},
7763         {0x00000012,    "Network"},
7764         {0x00000013,    "Network Browser"},
7765         {0x00000014,    "Network Filesystem"},
7766         {0x00000015,    "NULL"},
7767         {0x00000016,    "Parallel Port"},
7768         {0x00000017,    "Physical card"},
7769         {0x00000018,    "Printer"},
7770         {0x00000019,    "Scanner"},
7771         {0x0000001a,    "Serial Mouse port"},
7772         {0x0000001b,    "Serial port"},
7773         {0x0000001c,    "Screen"},
7774         {0x0000001d,    "Sound"},
7775         {0x0000001e,    "Streams"},
7776         {0x0000001f,    "Tape"},
7777         {0x00000020,    "Tape Filesystem"},
7778         {0x00000021,    "Transport"},
7779         {0x00000022,    "Unknown"},
7780         {0x00000023,    "Video"},
7781         {0x00000024,    "Virtual Disk"},
7782         {0x00000025,    "WAVE-In"},
7783         {0x00000026,    "WAVE-Out"},
7784         {0x00000027,    "8042 Port"},
7785         {0x00000028,    "Network Redirector"},
7786         {0x00000029,    "Battery"},
7787         {0x0000002a,    "Bus Extender"},
7788         {0x0000002b,    "Modem"},
7789         {0x0000002c,    "VDM"},
7790         {0,     NULL}
7791 };
7792
7793 static const value_string is_directory_vals[] = {
7794         {0,     "This is NOT a directory"},
7795         {1,     "This is a DIRECTORY"},
7796         {0, NULL}
7797 };
7798
7799 typedef struct _nt_trans_data {
7800         int subcmd;
7801         guint32 sd_len;
7802         guint32 ea_len;
7803 } nt_trans_data;
7804
7805
7806
7807 static int
7808 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7809 {
7810         guint8 mask;
7811         proto_item *item = NULL;
7812         proto_tree *tree = NULL;
7813
7814         mask = tvb_get_guint8(tvb, offset);
7815
7816         if(parent_tree){
7817                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7818                         "Security Flags: 0x%02x", mask);
7819                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
7820         }
7821
7822         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
7823                 tvb, offset, 1, mask);
7824         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
7825                 tvb, offset, 1, mask);
7826
7827         offset += 1;
7828
7829         return offset;
7830 }
7831
7832 /*
7833  * XXX - there are some more flags in the description of "ZwOpenFile()"
7834  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7835  * the wire as well?  (The spec at
7836  *
7837  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7838  *
7839  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7840  * via the SMB protocol.  The NT redirector should convert this option
7841  * to FILE_WRITE_THROUGH."
7842  *
7843  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7844  * values one would infer from their position in the list of flags for
7845  * "ZwOpenFile()".  Most of the others probably have those values
7846  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7847  * which might go over the wire (for the benefit of backup/restore software).
7848  */
7849 static const true_false_string tfs_nt_create_options_directory = {
7850         "File being created/opened must be a directory",
7851         "File being created/opened must not be a directory"
7852 };
7853 static const true_false_string tfs_nt_create_options_write_through = {
7854         "Writes should flush buffered data before completing",
7855         "Writes need not flush buffered data before completing"
7856 };
7857 static const true_false_string tfs_nt_create_options_sequential_only = {
7858         "The file will only be accessed sequentially",
7859         "The file might not only be accessed sequentially"
7860 };
7861 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
7862         "NO intermediate buffering is allowed",
7863         "Intermediate buffering is allowed"
7864 };
7865 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7866         "All operations SYNCHRONOUS, waits subject to termination from alert",
7867         "Operations NOT necessarily synchronous"
7868 };
7869 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7870         "All operations SYNCHRONOUS, waits not subject to alert",
7871         "Operations NOT necessarily synchronous"
7872 };
7873 static const true_false_string tfs_nt_create_options_non_directory = {
7874         "File being created/opened must not be a directory",
7875         "File being created/opened must be a directory"
7876 };
7877 static const true_false_string tfs_nt_create_options_create_tree_connection = {
7878         "Create Tree Connections is SET",
7879         "Create Tree Connections is NOT set"
7880 };
7881 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
7882         "Complete if oplocked is SET",
7883         "Complete if oplocked is NOT set"
7884 };
7885 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7886         "The client does not understand extended attributes",
7887         "The client understands extended attributes"
7888 };
7889 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7890         "The client understands only 8.3 file names",
7891         "The client understands long file names"
7892 };
7893 static const true_false_string tfs_nt_create_options_random_access = {
7894         "The file will be accessed randomly",
7895         "The file will not be accessed randomly"
7896 };
7897 static const true_false_string tfs_nt_create_options_delete_on_close = {
7898         "The file should be deleted when it is closed",
7899         "The file should not be deleted when it is closed"
7900 };
7901 static const true_false_string tfs_nt_create_options_open_by_fileid = {
7902         "OpenByFileID bit is SET",
7903         "OpenByFileID is NOT set"
7904 };
7905 static const true_false_string tfs_nt_create_options_backup_intent = {
7906         "This is a create with BACKUP INTENT",
7907         "This is a normal create"
7908 };
7909 static const true_false_string tfs_nt_create_options_no_compression = {
7910         "Open/Create with NO Compression",
7911         "Compression is allowed for Open/Create"
7912 };
7913 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
7914         "Reserve Opfilter is SET",
7915         "Reserve Opfilter is NOT set"
7916 };
7917 static const true_false_string tfs_nt_create_options_open_reparse_point = {
7918         "Open a Reparse Point",
7919         "Normal open"
7920 };
7921 static const true_false_string tfs_nt_create_options_open_no_recall = {
7922         "Open No Recall is SET",
7923         "Open no recall is NOT set"
7924 };
7925 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
7926         "This is an OPEN FOR FREE SPACE QUERY",
7927         "This is NOT an open for free space query"
7928 };
7929
7930 int
7931 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7932 {
7933         guint32 mask;
7934         proto_item *item = NULL;
7935         proto_tree *tree = NULL;
7936
7937         mask = tvb_get_letohl(tvb, offset);
7938
7939         if(parent_tree){
7940                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7941                         "Completion Filter: 0x%08x", mask);
7942                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7943         }
7944
7945         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7946                 tvb, offset, 4, mask);
7947         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7948                 tvb, offset, 4, mask);
7949         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7950                 tvb, offset, 4, mask);
7951         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7952                 tvb, offset, 4, mask);
7953         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7954                 tvb, offset, 4, mask);
7955         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7956                 tvb, offset, 4, mask);
7957         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7958                 tvb, offset, 4, mask);
7959         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7960                 tvb, offset, 4, mask);
7961         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7962                 tvb, offset, 4, mask);
7963         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7964                 tvb, offset, 4, mask);
7965         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7966                 tvb, offset, 4, mask);
7967         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7968                 tvb, offset, 4, mask);
7969
7970         offset += 4;
7971         return offset;
7972 }
7973
7974 static int
7975 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7976 {
7977         guint8 mask;
7978         proto_item *item = NULL;
7979         proto_tree *tree = NULL;
7980
7981         mask = tvb_get_guint8(tvb, offset);
7982
7983         if(parent_tree){
7984                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7985                         "Completion Filter: 0x%02x", mask);
7986                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7987         }
7988
7989         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7990                 tvb, offset, 1, mask);
7991
7992         offset += 1;
7993         return offset;
7994 }
7995
7996 /*
7997  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7998  * Native API Reference".
7999  */
8000 static const true_false_string tfs_nt_qsd_owner = {
8001         "Requesting OWNER security information",
8002         "NOT requesting owner security information",
8003 };
8004
8005 static const true_false_string tfs_nt_qsd_group = {
8006         "Requesting GROUP security information",
8007         "NOT requesting group security information",
8008 };
8009
8010 static const true_false_string tfs_nt_qsd_dacl = {
8011         "Requesting DACL security information",
8012         "NOT requesting DACL security information",
8013 };
8014
8015 static const true_false_string tfs_nt_qsd_sacl = {
8016         "Requesting SACL security information",
8017         "NOT requesting SACL security information",
8018 };
8019
8020 #define NT_QSD_OWNER    0x00000001
8021 #define NT_QSD_GROUP    0x00000002
8022 #define NT_QSD_DACL     0x00000004
8023 #define NT_QSD_SACL     0x00000008
8024
8025 int
8026 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8027 {
8028         guint32 mask;
8029         proto_item *item = NULL;
8030         proto_tree *tree = NULL;
8031
8032         mask = tvb_get_letohl(tvb, offset);
8033
8034         if(parent_tree){
8035                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8036                         "Security Information: 0x%08x", mask);
8037                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8038         }
8039
8040         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8041                 tvb, offset, 4, mask);
8042         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8043                 tvb, offset, 4, mask);
8044         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8045                 tvb, offset, 4, mask);
8046         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8047                 tvb, offset, 4, mask);
8048
8049         offset += 4;
8050
8051         return offset;
8052 }
8053
8054 static int
8055 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8056 {
8057         int old_offset, old_sid_offset;
8058         guint32 qsize;
8059
8060         do {
8061                 old_offset=offset;
8062
8063                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8064                 qsize=tvb_get_letohl(tvb, offset);
8065                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8066                 COUNT_BYTES_TRANS_SUBR(4);
8067
8068                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8069                 /* length of SID */
8070                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8071                 COUNT_BYTES_TRANS_SUBR(4);
8072
8073                 /* 16 unknown bytes */
8074                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8075                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8076                             offset, 8, TRUE);
8077                 COUNT_BYTES_TRANS_SUBR(8);
8078
8079                 /* number of bytes for used quota */
8080                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8081                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8082                 COUNT_BYTES_TRANS_SUBR(8);
8083
8084                 /* number of bytes for quota warning */
8085                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8086                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8087                 COUNT_BYTES_TRANS_SUBR(8);
8088
8089                 /* number of bytes for quota limit */
8090                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8091                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8092                 COUNT_BYTES_TRANS_SUBR(8);
8093
8094                 /* SID of the user */
8095                 old_sid_offset=offset;
8096                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8097                 *bcp -= (offset-old_sid_offset);
8098
8099                 if(qsize){
8100                         offset = old_offset+qsize;
8101                 }
8102         }while(qsize);
8103
8104
8105         return offset;
8106 }
8107
8108
8109 static int
8110 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)
8111 {
8112         proto_item *item = NULL;
8113         proto_tree *tree = NULL;
8114         smb_info_t *si;
8115         int old_offset = offset;
8116         guint16 bcp=bc; /* XXX fixme */
8117         struct access_mask_info *ami=NULL;
8118         tvbuff_t *ioctl_tvb;
8119
8120         si = (smb_info_t *)pinfo->private_data;
8121
8122         DISSECTOR_ASSERT(si);
8123
8124         if(parent_tree){
8125                 tvb_ensure_bytes_exist(tvb, offset, bc);
8126                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8127                                 "%s Data",
8128                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8129                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8130         }
8131
8132         switch(ntd->subcmd){
8133         case NT_TRANS_CREATE:
8134                 /* security descriptor */
8135                 if(ntd->sd_len){
8136                         offset = dissect_nt_sec_desc(
8137                                 tvb, offset, pinfo, tree, NULL, TRUE,
8138                                 ntd->sd_len, NULL);
8139                 }
8140
8141                 /* extended attributes */
8142                 if(ntd->ea_len){
8143                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8144                         offset += ntd->ea_len;
8145                 }
8146
8147                 break;
8148         case NT_TRANS_IOCTL:
8149                 /* ioctl data */
8150                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8151                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
8152
8153
8154                 offset += bc;
8155
8156                 break;
8157         case NT_TRANS_SSD:
8158                 if(nti){
8159                         switch(nti->fid_type){
8160                         case SMB_FID_TYPE_FILE:
8161                                 ami= &smb_file_access_mask_info;
8162                                 break;
8163                         case SMB_FID_TYPE_DIR:
8164                                 ami= &smb_dir_access_mask_info;
8165                                 break;
8166                         }
8167                 }
8168
8169                 offset = dissect_nt_sec_desc(
8170                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8171                 break;
8172         case NT_TRANS_NOTIFY:
8173                 break;
8174         case NT_TRANS_RENAME:
8175                 /* XXX not documented */
8176                 break;
8177         case NT_TRANS_QSD:
8178                 break;
8179         case NT_TRANS_GET_USER_QUOTA:
8180                 /* unknown 4 bytes */
8181                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8182                             offset, 4, TRUE);
8183                 offset += 4;
8184
8185                 /* length of SID */
8186                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8187                 offset +=4;
8188
8189                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8190                 break;
8191         case NT_TRANS_SET_USER_QUOTA:
8192                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8193                 break;
8194         }
8195
8196         /* ooops there were data we didnt know how to process */
8197         if((offset-old_offset) < bc){
8198                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8199                     bc - (offset-old_offset), TRUE);
8200                 offset += bc - (offset-old_offset);
8201         }
8202
8203         return offset;
8204 }
8205
8206 static int
8207 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)
8208 {
8209         proto_item *item = NULL;
8210         proto_tree *tree = NULL;
8211         smb_info_t *si;
8212         guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options, create_disposition;
8213         const char *fn;
8214
8215         si = (smb_info_t *)pinfo->private_data;
8216
8217         DISSECTOR_ASSERT(si);
8218
8219         if(parent_tree){
8220                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8221                                 "%s Parameters",
8222                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8223                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8224         }
8225
8226         switch(ntd->subcmd){
8227         case NT_TRANS_CREATE:
8228                 /* Create flags */
8229                 create_flags=tvb_get_letohl(tvb, offset);
8230                 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8231                 bc -= 4;
8232
8233                 /* root directory fid */
8234                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8235                 COUNT_BYTES(4);
8236
8237                 /* nt access mask */
8238                 access_mask=tvb_get_letohl(tvb, offset);
8239                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8240                 bc -= 4;
8241
8242                 /* allocation size */
8243                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8244                 COUNT_BYTES(8);
8245
8246                 /* Extended File Attributes */
8247                 file_attributes=tvb_get_letohl(tvb, offset);
8248                 offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
8249                 bc -= 4;
8250
8251                 /* share access */
8252                 share_access=tvb_get_letohl(tvb, offset);
8253                 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8254                 bc -= 4;
8255
8256                 /* create disposition */
8257                 create_disposition=tvb_get_letohl(tvb, offset);
8258                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8259                 COUNT_BYTES(4);
8260
8261                 /* create options */
8262                 create_options=tvb_get_letohl(tvb, offset);
8263                 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8264                 bc -= 4;
8265
8266                 /* sd length */
8267                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8268                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8269                 COUNT_BYTES(4);
8270
8271                 /* ea length */
8272                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8273                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8274                 COUNT_BYTES(4);
8275
8276                 /* file name len */
8277                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8278                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8279                 COUNT_BYTES(4);
8280
8281                 /* impersonation level */
8282                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8283                 COUNT_BYTES(4);
8284
8285                 /* security flags */
8286                 offset = dissect_nt_security_flags(tvb, tree, offset);
8287                 bc -= 1;
8288
8289                 /* file name */
8290                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8291                 if (fn != NULL) {
8292                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8293                                 fn);
8294                         COUNT_BYTES(fn_len);
8295                 }
8296
8297                 break;
8298         case NT_TRANS_IOCTL:
8299                 break;
8300         case NT_TRANS_SSD: {
8301                 guint16 fid;
8302                 smb_fid_info_t *fid_info;
8303
8304                 /* fid */
8305                 fid = tvb_get_letohs(tvb, offset);
8306                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8307                 offset += 2;
8308                 if(nti){
8309                         if(fid_info){
8310                                 nti->fid_type=fid_info->type;
8311                         } else {
8312                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8313                         }
8314                 }
8315
8316                 /* 2 reserved bytes */
8317                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8318                 offset += 2;
8319
8320                 /* security information */
8321                 offset = dissect_security_information_mask(tvb, tree, offset);
8322                 break;
8323         }
8324         case NT_TRANS_NOTIFY:
8325                 break;
8326         case NT_TRANS_RENAME:
8327                 /* XXX not documented */
8328                 break;
8329         case NT_TRANS_QSD: {
8330                 guint16 fid;
8331                 smb_fid_info_t *fid_info;
8332
8333                 /* fid */
8334                 fid = tvb_get_letohs(tvb, offset);
8335                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8336                 offset += 2;
8337                 if(nti){
8338                         if(fid_info){
8339                                 nti->fid_type=fid_info->type;
8340                         } else {
8341                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8342                         }
8343                 }
8344
8345                 /* 2 reserved bytes */
8346                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8347                 offset += 2;
8348
8349                 /* security information */
8350                 offset = dissect_security_information_mask(tvb, tree, offset);
8351                 break;
8352         }
8353         case NT_TRANS_GET_USER_QUOTA:
8354                 /* not decoded yet */
8355                 break;
8356         case NT_TRANS_SET_USER_QUOTA:
8357                 /* not decoded yet */
8358                 break;
8359         }
8360
8361         return offset;
8362 }
8363
8364 static int
8365 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8366 {
8367         proto_item *item = NULL;
8368         proto_tree *tree = NULL;
8369         int old_offset = offset;
8370         smb_info_t *si;
8371         smb_nt_transact_info_t *nti;
8372         smb_saved_info_t *sip;
8373
8374
8375         si = (smb_info_t *)pinfo->private_data;
8376         DISSECTOR_ASSERT(si);
8377         sip = si->sip;
8378         DISSECTOR_ASSERT(sip);
8379         nti=sip->extra_info;
8380
8381
8382         if(parent_tree){
8383                 tvb_ensure_bytes_exist(tvb, offset, len);
8384                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8385                                 "%s Setup",
8386                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8387                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8388         }
8389
8390         switch(ntd->subcmd){
8391         case NT_TRANS_CREATE:
8392                 break;
8393         case NT_TRANS_IOCTL: {
8394                 guint16 fid;
8395
8396                 /* function code */
8397                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
8398
8399                 /* fid */
8400                 fid = tvb_get_letohs(tvb, offset);
8401                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8402                 offset += 2;
8403
8404                 /* isfsctl */
8405                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8406                 offset += 1;
8407
8408                 /* isflags */
8409                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8410
8411                 break;
8412         }
8413         case NT_TRANS_SSD:
8414                 break;
8415         case NT_TRANS_NOTIFY: {
8416                 guint16 fid;
8417
8418                 /* completion filter */
8419                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8420
8421                 /* fid */
8422                 fid = tvb_get_letohs(tvb, offset);
8423                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8424                 offset += 2;
8425
8426                 /* watch tree */
8427                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8428                 offset += 1;
8429
8430                 /* reserved byte */
8431                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8432                 offset += 1;
8433
8434                 break;
8435         }
8436         case NT_TRANS_RENAME:
8437                 /* XXX not documented */
8438                 break;
8439         case NT_TRANS_QSD:
8440                 break;
8441         case NT_TRANS_GET_USER_QUOTA:
8442                 /* not decoded yet */
8443                 break;
8444         case NT_TRANS_SET_USER_QUOTA:
8445                 /* not decoded yet */
8446                 break;
8447         }
8448
8449         return old_offset+len;
8450 }
8451
8452
8453 static int
8454 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8455 {
8456         guint8 wc, sc;
8457         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8458         smb_info_t *si;
8459         smb_saved_info_t *sip;
8460         int subcmd;
8461         nt_trans_data ntd;
8462         guint16 bc;
8463         guint32 padcnt;
8464         smb_nt_transact_info_t *nti=NULL;
8465
8466         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8467
8468         si = (smb_info_t *)pinfo->private_data;
8469         DISSECTOR_ASSERT(si);
8470         sip = si->sip;
8471
8472         WORD_COUNT;
8473
8474         if(wc>=19){
8475                 /* primary request */
8476                 /* max setup count */
8477                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8478                 offset += 1;
8479
8480                 /* 2 reserved bytes */
8481                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8482                 offset += 2;
8483         } else {
8484                 /* secondary request */
8485                 /* 3 reserved bytes */
8486                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8487                 offset += 3;
8488         }
8489
8490
8491         /* total param count */
8492         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8493         offset += 4;
8494
8495         /* total data count */
8496         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8497         offset += 4;
8498
8499         if(wc>=19){
8500                 /* primary request */
8501                 /* max param count */
8502                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8503                 offset += 4;
8504
8505                 /* max data count */
8506                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8507                 offset += 4;
8508         }
8509
8510         /* param count */
8511         pc = tvb_get_letohl(tvb, offset);
8512         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8513         offset += 4;
8514
8515         /* param offset */
8516         po = tvb_get_letohl(tvb, offset);
8517         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8518         offset += 4;
8519
8520         /* param displacement */
8521         if(wc>=19){
8522                 /* primary request*/
8523                 pd = 0;
8524         } else {
8525                 /* secondary request */
8526                 pd = tvb_get_letohl(tvb, offset);
8527                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8528                 offset += 4;
8529         }
8530
8531         /* data count */
8532         dc = tvb_get_letohl(tvb, offset);
8533         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8534         offset += 4;
8535
8536         /* data offset */
8537         od = tvb_get_letohl(tvb, offset);
8538         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8539         offset += 4;
8540
8541         /* data displacement */
8542         if(wc>=19){
8543                 /* primary request */
8544                 dd = 0;
8545         } else {
8546                 /* secondary request */
8547                 dd = tvb_get_letohl(tvb, offset);
8548                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8549                 offset += 4;
8550         }
8551
8552         /* setup count */
8553         if(wc>=19){
8554                 /* primary request */
8555                 sc = tvb_get_guint8(tvb, offset);
8556                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8557                 offset += 1;
8558         } else {
8559                 /* secondary request */
8560                 sc = 0;
8561         }
8562
8563         /* function */
8564         if(wc>=19){
8565                 /* primary request */
8566                 subcmd = tvb_get_letohs(tvb, offset);
8567                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8568                 if(check_col(pinfo->cinfo, COL_INFO)){
8569                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8570                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8571                 }
8572                 ntd.subcmd = subcmd;
8573                 if (!si->unidir && sip) {
8574                         if(!pinfo->fd->flags.visited){
8575                                 /*
8576                                  * Allocate a new smb_nt_transact_info_t
8577                                  * structure.
8578                                  */
8579                                 nti = se_alloc(sizeof(smb_nt_transact_info_t));
8580                                 nti->subcmd = subcmd;
8581                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8582                                 sip->extra_info = nti;
8583                                 sip->extra_info_type = SMB_EI_NTI;
8584                         } else {
8585                                 if(sip->extra_info_type == SMB_EI_NTI){
8586                                         nti=sip->extra_info;
8587                                 }
8588                         }
8589                 }
8590         } else {
8591                 /* secondary request */
8592                 if(check_col(pinfo->cinfo, COL_INFO)){
8593                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8594                 }
8595         }
8596         offset += 2;
8597
8598         /* this is a padding byte */
8599         if(offset%1){
8600                 /* pad byte */
8601                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8602                 offset += 1;
8603         }
8604
8605         /* if there were any setup bytes, decode them */
8606         if(sc){
8607                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8608                 offset += sc*2;
8609         }
8610
8611         BYTE_COUNT;
8612
8613         /* parameters */
8614         if(po>(guint32)offset){
8615                 /* We have some initial padding bytes.
8616                 */
8617                 padcnt = po-offset;
8618                 if (padcnt > bc)
8619                         padcnt = bc;
8620                 CHECK_BYTE_COUNT(padcnt);
8621                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8622                 COUNT_BYTES(padcnt);
8623         }
8624         if(pc){
8625                 CHECK_BYTE_COUNT(pc);
8626                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti);
8627                 COUNT_BYTES(pc);
8628         }
8629
8630         /* data */
8631         if(od>(guint32)offset){
8632                 /* We have some initial padding bytes.
8633                 */
8634                 padcnt = od-offset;
8635                 if (padcnt > bc)
8636                         padcnt = bc;
8637                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8638                 COUNT_BYTES(padcnt);
8639         }
8640         if(dc){
8641                 CHECK_BYTE_COUNT(dc);
8642                 dissect_nt_trans_data_request(
8643                         tvb, pinfo, offset, tree, dc, &ntd, nti);
8644                 COUNT_BYTES(dc);
8645         }
8646
8647         END_OF_SMB
8648
8649         return offset;
8650 }
8651
8652
8653
8654 static int
8655 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8656                                int offset, proto_tree *parent_tree, int len,
8657                                nt_trans_data *ntd _U_,
8658                                smb_nt_transact_info_t *nti)
8659 {
8660         proto_item *item = NULL;
8661         proto_tree *tree = NULL;
8662         smb_info_t *si;
8663         guint16 bcp;
8664         struct access_mask_info *ami=NULL;
8665         tvbuff_t *ioctl_tvb;
8666
8667         si = (smb_info_t *)pinfo->private_data;
8668         DISSECTOR_ASSERT(si);
8669
8670         if(parent_tree){
8671                 tvb_ensure_bytes_exist(tvb, offset, len);
8672                 if(nti != NULL){
8673                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8674                                 "%s Data",
8675                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8676                 } else {
8677                         /*
8678                          * We never saw the request to which this is a
8679                          * response.
8680                          */
8681                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8682                                 "Unknown NT Transaction Data (matching request not seen)");
8683                 }
8684                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8685         }
8686
8687         if (nti == NULL) {
8688                 offset += len;
8689                 return offset;
8690         }
8691         switch(nti->subcmd){
8692         case NT_TRANS_CREATE:
8693                 break;
8694         case NT_TRANS_IOCTL:
8695                 /* ioctl data */
8696                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
8697                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
8698
8699                 offset += len;
8700
8701                 break;
8702         case NT_TRANS_SSD:
8703                 break;
8704         case NT_TRANS_NOTIFY:
8705                 break;
8706         case NT_TRANS_RENAME:
8707                 /* XXX not documented */
8708                 break;
8709         case NT_TRANS_QSD:
8710                 if(nti){
8711                         switch(nti->fid_type){
8712                         case SMB_FID_TYPE_FILE:
8713                                 ami= &smb_file_access_mask_info;
8714                                 break;
8715                         case SMB_FID_TYPE_DIR:
8716                                 ami= &smb_dir_access_mask_info;
8717                                 break;
8718                         }
8719                 }
8720                 offset = dissect_nt_sec_desc(
8721                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
8722                 break;
8723         case NT_TRANS_GET_USER_QUOTA:
8724                 bcp=len;
8725                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8726                 break;
8727         case NT_TRANS_SET_USER_QUOTA:
8728                 /* not decoded yet */
8729                 break;
8730         }
8731
8732         return offset;
8733 }
8734
8735 static int
8736 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8737                                 int offset, proto_tree *parent_tree,
8738                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8739 {
8740         proto_item *item = NULL;
8741         proto_tree *tree = NULL;
8742         guint32 fn_len;
8743         const char *fn;
8744         smb_info_t *si;
8745         smb_nt_transact_info_t *nti;
8746         guint16 fid;
8747         int old_offset;
8748         guint32 neo;
8749         int padcnt;
8750         smb_fid_info_t *fid_info=NULL;
8751         guint16 ftype;
8752         guint8  isdir;
8753
8754         si = (smb_info_t *)pinfo->private_data;
8755         DISSECTOR_ASSERT(si);
8756
8757         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8758                 nti = si->sip->extra_info;
8759         else
8760                 nti = NULL;
8761
8762         if(parent_tree){
8763                 tvb_ensure_bytes_exist(tvb, offset, len);
8764                 if(nti != NULL){
8765                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8766                                 "%s Parameters",
8767                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8768                 } else {
8769                         /*
8770                          * We never saw the request to which this is a
8771                          * response.
8772                          */
8773                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8774                                 "Unknown NT Transaction Parameters (matching request not seen)");
8775                 }
8776                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8777         }
8778
8779         if (nti == NULL) {
8780                 offset += len;
8781                 return offset;
8782         }
8783         switch(nti->subcmd){
8784         case NT_TRANS_CREATE:
8785                 /* oplock level */
8786                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8787                 offset += 1;
8788
8789                 /* reserved byte */
8790                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8791                 offset += 1;
8792
8793                 /* fid */
8794                 fid = tvb_get_letohs(tvb, offset);
8795                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
8796                 offset += 2;
8797
8798                 /* create action */
8799                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8800                 offset += 4;
8801
8802                 /* ea error offset */
8803                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8804                 offset += 4;
8805
8806                 /* create time */
8807                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8808                         hf_smb_create_time);
8809
8810                 /* access time */
8811                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8812                         hf_smb_access_time);
8813
8814                 /* last write time */
8815                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8816                         hf_smb_last_write_time);
8817
8818                 /* last change time */
8819                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8820                         hf_smb_change_time);
8821
8822                 /* Extended File Attributes */
8823                 offset = dissect_file_ext_attr(tvb, tree, offset);
8824
8825                 /* allocation size */
8826                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8827                 offset += 8;
8828
8829                 /* end of file */
8830                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8831                 offset += 8;
8832
8833                 /* File Type */
8834                 ftype=tvb_get_letohs(tvb, offset);
8835                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8836                 offset += 2;
8837
8838                 /* device state */
8839                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8840
8841                 /* is directory */
8842                 isdir=tvb_get_guint8(tvb, offset);
8843                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8844                 offset += 1;
8845
8846                 /* Try to remember the type of this fid so that we can dissect
8847                  * any future security descriptor (access mask) properly
8848                  */
8849                 if(ftype==0){
8850                         if(isdir==0){
8851                                 if(fid_info){
8852                                         fid_info->type=SMB_FID_TYPE_FILE;
8853                                 }
8854                         } else {
8855                                 if(fid_info){
8856                                         fid_info->type=SMB_FID_TYPE_DIR;
8857                                 }
8858                         }
8859                 }
8860                 if(ftype==2){
8861                         if(fid_info){
8862                                 fid_info->type=SMB_FID_TYPE_PIPE;
8863                         }
8864                 }               
8865                 break;
8866         case NT_TRANS_IOCTL:
8867                 break;
8868         case NT_TRANS_SSD:
8869                 break;
8870         case NT_TRANS_NOTIFY:
8871                 while(len){
8872                         old_offset = offset;
8873
8874                         /* next entry offset */
8875                         neo = tvb_get_letohl(tvb, offset);
8876                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8877                         COUNT_BYTES(4);
8878                         len -= 4;
8879                         /* broken implementations */
8880                         if(len<0)break;
8881
8882                         /* action */
8883                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8884                         COUNT_BYTES(4);
8885                         len -= 4;
8886                         /* broken implementations */
8887                         if(len<0)break;
8888
8889                         /* file name len */
8890                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8891                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8892                         COUNT_BYTES(4);
8893                         len -= 4;
8894                         /* broken implementations */
8895                         if(len<0)break;
8896
8897                         /* file name */
8898                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8899                         if (fn == NULL)
8900                                 break;
8901                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8902                                 fn);
8903                         COUNT_BYTES(fn_len);
8904                         len -= fn_len;
8905                         /* broken implementations */
8906                         if(len<0)break;
8907
8908                         if (neo == 0)
8909                                 break;  /* no more structures */
8910
8911                         /* skip to next structure */
8912                         padcnt = (old_offset + neo) - offset;
8913                         if (padcnt < 0) {
8914                                 /*
8915                                  * XXX - this is bogus; flag it?
8916                                  */
8917                                 padcnt = 0;
8918                         }
8919                         if (padcnt != 0) {
8920                                 COUNT_BYTES(padcnt);
8921                                 len -= padcnt;
8922                                 /* broken implementations */
8923                                 if(len<0)break;
8924                         }
8925                 }
8926                 break;
8927         case NT_TRANS_RENAME:
8928                 /* XXX not documented */
8929                 break;
8930         case NT_TRANS_QSD:
8931                 /*
8932                  * This appears to be the size of the security
8933                  * descriptor; the calling sequence of
8934                  * "ZwQuerySecurityObject()" suggests that it would
8935                  * be.  The actual security descriptor wouldn't
8936                  * follow if the max data count in the request
8937                  * was smaller; this lets the client know how
8938                  * big a buffer it needs to provide.
8939                  */
8940                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8941                 offset += 4;
8942                 break;
8943         case NT_TRANS_GET_USER_QUOTA:
8944                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8945                         tvb_get_letohl(tvb, offset));
8946                 offset += 4;
8947                 break;
8948         case NT_TRANS_SET_USER_QUOTA:
8949                 /* not decoded yet */
8950                 break;
8951         }
8952
8953         return offset;
8954 }
8955
8956 static int
8957 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8958                                 int offset, proto_tree *parent_tree,
8959                                 int len, nt_trans_data *ntd _U_)
8960 {
8961         proto_item *item = NULL;
8962         proto_tree *tree = NULL;
8963         smb_info_t *si;
8964         smb_nt_transact_info_t *nti;
8965
8966         si = (smb_info_t *)pinfo->private_data;
8967         DISSECTOR_ASSERT(si);
8968
8969         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8970                 nti = si->sip->extra_info;
8971         else
8972                 nti = NULL;
8973
8974         if(parent_tree){
8975                 tvb_ensure_bytes_exist(tvb, offset, len);
8976                 if(nti != NULL){
8977                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8978                                 "%s Setup",
8979                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8980                 } else {
8981                         /*
8982                          * We never saw the request to which this is a
8983                          * response.
8984                          */
8985                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8986                                 "Unknown NT Transaction Setup (matching request not seen)");
8987                 }
8988                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8989         }
8990
8991         if (nti == NULL) {
8992                 offset += len;
8993                 return offset;
8994         }
8995         switch(nti->subcmd){
8996         case NT_TRANS_CREATE:
8997                 break;
8998         case NT_TRANS_IOCTL:
8999                 break;
9000         case NT_TRANS_SSD:
9001                 break;
9002         case NT_TRANS_NOTIFY:
9003                 break;
9004         case NT_TRANS_RENAME:
9005                 /* XXX not documented */
9006                 break;
9007         case NT_TRANS_QSD:
9008                 break;
9009         case NT_TRANS_GET_USER_QUOTA:
9010                 /* not decoded yet */
9011                 break;
9012         case NT_TRANS_SET_USER_QUOTA:
9013                 /* not decoded yet */
9014                 break;
9015         }
9016
9017         return offset;
9018 }
9019
9020 static int
9021 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9022 {
9023         guint8 wc, sc;
9024         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
9025         guint32 td=0, tp=0;
9026         smb_info_t *si;
9027         smb_nt_transact_info_t *nti=NULL;
9028         static nt_trans_data ntd;
9029         guint16 bc;
9030         gint32 padcnt;
9031         fragment_data *r_fd = NULL;
9032         tvbuff_t *pd_tvb=NULL;
9033         gboolean save_fragmented;
9034
9035         si = (smb_info_t *)pinfo->private_data;
9036         DISSECTOR_ASSERT(si);
9037
9038         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9039                 nti = si->sip->extra_info;
9040         else
9041                 nti = NULL;
9042
9043         /* primary request */
9044         if(nti != NULL){
9045                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9046                 if(check_col(pinfo->cinfo, COL_INFO)){
9047                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9048                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
9049                 }
9050         } else {
9051                 proto_tree_add_text(tree, tvb, offset, 0,
9052                         "Function: <unknown function - could not find matching request>");
9053                 if(check_col(pinfo->cinfo, COL_INFO)){
9054                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
9055                 }
9056         }
9057
9058         WORD_COUNT;
9059
9060         /* 3 reserved bytes */
9061         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9062         offset += 3;
9063
9064         /* total param count */
9065         tp = tvb_get_letohl(tvb, offset);
9066         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9067         offset += 4;
9068
9069         /* total data count */
9070         td = tvb_get_letohl(tvb, offset);
9071         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9072         offset += 4;
9073
9074         /* param count */
9075         pc = tvb_get_letohl(tvb, offset);
9076         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9077         offset += 4;
9078
9079         /* param offset */
9080         po = tvb_get_letohl(tvb, offset);
9081         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9082         offset += 4;
9083
9084         /* param displacement */
9085         pd = tvb_get_letohl(tvb, offset);
9086         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9087         offset += 4;
9088
9089         /* data count */
9090         dc = tvb_get_letohl(tvb, offset);
9091         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9092         offset += 4;
9093
9094         /* data offset */
9095         od = tvb_get_letohl(tvb, offset);
9096         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9097         offset += 4;
9098
9099         /* data displacement */
9100         dd = tvb_get_letohl(tvb, offset);
9101         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9102         offset += 4;
9103
9104         /* setup count */
9105         sc = tvb_get_guint8(tvb, offset);
9106         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9107         offset += 1;
9108
9109         /* setup data */
9110         if(sc){
9111                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
9112                 offset += sc*2;
9113         }
9114
9115         BYTE_COUNT;
9116
9117         /* reassembly of SMB NT Transaction data payload.
9118            In this section we do reassembly of both the data and parameters
9119            blocks of the SMB transaction command.
9120         */
9121         save_fragmented = pinfo->fragmented;
9122         /* do we need reassembly? */
9123         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
9124                 /* oh yeah, either data or parameter section needs
9125                    reassembly...
9126                 */
9127                 pinfo->fragmented = TRUE;
9128                 if(smb_trans_reassembly){
9129                         /* ...and we were told to do reassembly */
9130                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
9131                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9132                                                              po, pc, pd, td+tp);
9133
9134                         }
9135                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
9136                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9137                                                              od, dc, dd+tp, td+tp);
9138                         }
9139                 }
9140         }
9141
9142         /* if we got a reassembled fd structure from the reassembly routine we
9143            must create pd_tvb from it
9144         */
9145         if(r_fd){
9146         proto_item *frag_tree_item;
9147
9148                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
9149                                              r_fd->datalen);
9150                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
9151                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9152
9153                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9154         }
9155
9156
9157         if(pd_tvb){
9158           /* we have reassembled data, grab param and data from there */
9159           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9160                                           &ntd, (guint16) tvb_length(pd_tvb));
9161           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
9162         } else {
9163           /* we do not have reassembled data, just use what we have in the
9164              packet as well as we can */
9165           /* parameters */
9166           if(po>(guint32)offset){
9167             /* We have some initial padding bytes.
9168              */
9169             padcnt = po-offset;
9170             if (padcnt > bc)
9171               padcnt = bc;
9172             CHECK_BYTE_COUNT(padcnt);
9173             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9174             COUNT_BYTES(padcnt);
9175           }
9176           if(pc){
9177             CHECK_BYTE_COUNT(pc);
9178             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
9179             COUNT_BYTES(pc);
9180           }
9181
9182           /* data */
9183           if(od>(guint32)offset){
9184             /* We have some initial padding bytes.
9185              */
9186             padcnt = od-offset;
9187             if (padcnt > bc)
9188               padcnt = bc;
9189             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9190             COUNT_BYTES(padcnt);
9191           }
9192           if(dc){
9193             CHECK_BYTE_COUNT(dc);
9194             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti);
9195             COUNT_BYTES(dc);
9196           }
9197         }
9198         pinfo->fragmented = save_fragmented;
9199
9200         END_OF_SMB
9201
9202         return offset;
9203 }
9204
9205 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9206    NT Transaction command  ends here
9207    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9208
9209 static const value_string print_mode_vals[] = {
9210         {0,     "Text Mode"},
9211         {1,     "Graphics Mode"},
9212         {0, NULL}
9213 };
9214
9215 static int
9216 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9217 {
9218         smb_info_t *si = pinfo->private_data;
9219         int fn_len;
9220         const char *fn;
9221         guint8 wc;
9222         guint16 bc;
9223
9224         DISSECTOR_ASSERT(si);
9225
9226         WORD_COUNT;
9227
9228         /* setup len */
9229         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9230         offset += 2;
9231
9232         /* print mode */
9233         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9234         offset += 2;
9235
9236         BYTE_COUNT;
9237
9238         /* buffer format */
9239         CHECK_BYTE_COUNT(1);
9240         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9241         COUNT_BYTES(1);
9242
9243         /* print identifier */
9244         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9245         if (fn == NULL)
9246                 goto endofcommand;
9247         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9248                 fn);
9249         COUNT_BYTES(fn_len);
9250
9251         END_OF_SMB
9252
9253         return offset;
9254 }
9255
9256
9257 static int
9258 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9259 {
9260         int cnt;
9261         guint8 wc;
9262         guint16 bc, fid;
9263
9264         WORD_COUNT;
9265
9266         /* fid */
9267         fid = tvb_get_letohs(tvb, offset);
9268         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
9269         offset += 2;
9270
9271         BYTE_COUNT;
9272
9273         /* buffer format */
9274         CHECK_BYTE_COUNT(1);
9275         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9276         COUNT_BYTES(1);
9277
9278         /* data len */
9279         CHECK_BYTE_COUNT(2);
9280         cnt = tvb_get_letohs(tvb, offset);
9281         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9282         COUNT_BYTES(2);
9283
9284         /* file data */
9285         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9286
9287         END_OF_SMB
9288
9289         return offset;
9290 }
9291
9292
9293 static const value_string print_status_vals[] = {
9294         {1,     "Held or Stopped"},
9295         {2,     "Printing"},
9296         {3,     "Awaiting print"},
9297         {4,     "In intercept"},
9298         {5,     "File had error"},
9299         {6,     "Printer error"},
9300         {0, NULL}
9301 };
9302
9303 static int
9304 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9305 {
9306         guint8 wc;
9307         guint16 bc;
9308
9309         WORD_COUNT;
9310
9311         /* max count */
9312         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9313         offset += 2;
9314
9315         /* start index */
9316         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9317         offset += 2;
9318
9319         BYTE_COUNT;
9320
9321         END_OF_SMB
9322
9323         return offset;
9324 }
9325
9326 static int
9327 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9328     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9329 {
9330         proto_item *item = NULL;
9331         proto_tree *tree = NULL;
9332         smb_info_t *si = pinfo->private_data;
9333         int fn_len;
9334         const char *fn;
9335
9336         DISSECTOR_ASSERT(si);
9337
9338         if(parent_tree){
9339                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9340                         "Queue entry");
9341                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9342         }
9343
9344         /* queued time */
9345         CHECK_BYTE_COUNT_SUBR(4);
9346         offset = dissect_smb_datetime(tvb, tree, offset,
9347                 hf_smb_print_queue_date,
9348                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9349         *bcp -= 4;
9350
9351         /* status */
9352         CHECK_BYTE_COUNT_SUBR(1);
9353         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9354         COUNT_BYTES_SUBR(1);
9355
9356         /* spool file number */
9357         CHECK_BYTE_COUNT_SUBR(2);
9358         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9359         COUNT_BYTES_SUBR(2);
9360
9361         /* spool file size */
9362         CHECK_BYTE_COUNT_SUBR(4);
9363         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9364         COUNT_BYTES_SUBR(4);
9365
9366         /* reserved byte */
9367         CHECK_BYTE_COUNT_SUBR(1);
9368         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9369         COUNT_BYTES_SUBR(1);
9370
9371         /* file name */
9372         fn_len = 16;
9373         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9374         CHECK_STRING_SUBR(fn);
9375         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9376                 fn);
9377         COUNT_BYTES_SUBR(fn_len);
9378
9379         *trunc = FALSE;
9380         return offset;
9381 }
9382
9383 static int
9384 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9385 {
9386         guint16 cnt=0, len;
9387         guint8 wc;
9388         guint16 bc;
9389         gboolean trunc;
9390
9391         WORD_COUNT;
9392
9393         /* count */
9394         cnt = tvb_get_letohs(tvb, offset);
9395         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9396         offset += 2;
9397
9398         /* restart index */
9399         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9400         offset += 2;
9401
9402         BYTE_COUNT;
9403
9404         /* buffer format */
9405         CHECK_BYTE_COUNT(1);
9406         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9407         COUNT_BYTES(1);
9408
9409         /* data len */
9410         CHECK_BYTE_COUNT(2);
9411         len = tvb_get_letohs(tvb, offset);
9412         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9413         COUNT_BYTES(2);
9414
9415         /* queue elements */
9416         while(cnt--){
9417                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9418                     &bc, &trunc);
9419                 if (trunc)
9420                         goto endofcommand;
9421         }
9422
9423         END_OF_SMB
9424
9425         return offset;
9426 }
9427
9428
9429 static int
9430 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9431 {
9432         int name_len;
9433         guint16 bc;
9434         guint8 wc;
9435         guint16 message_len;
9436
9437         WORD_COUNT;
9438
9439         BYTE_COUNT;
9440
9441         /* buffer format */
9442         CHECK_BYTE_COUNT(1);
9443         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9444         COUNT_BYTES(1);
9445
9446         /* originator name */
9447         /* XXX - what if this runs past bc? */
9448         name_len = tvb_strsize(tvb, offset);
9449         CHECK_BYTE_COUNT(name_len);
9450         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9451             name_len, TRUE);
9452         COUNT_BYTES(name_len);
9453
9454         /* buffer format */
9455         CHECK_BYTE_COUNT(1);
9456         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9457         COUNT_BYTES(1);
9458
9459         /* destination name */
9460         /* XXX - what if this runs past bc? */
9461         name_len = tvb_strsize(tvb, offset);
9462         CHECK_BYTE_COUNT(name_len);
9463         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9464             name_len, TRUE);
9465         COUNT_BYTES(name_len);
9466
9467         /* buffer format */
9468         CHECK_BYTE_COUNT(1);
9469         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9470         COUNT_BYTES(1);
9471
9472         /* message len */
9473         CHECK_BYTE_COUNT(2);
9474         message_len = tvb_get_letohs(tvb, offset);
9475         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9476             message_len);
9477         COUNT_BYTES(2);
9478
9479         /* message */
9480         CHECK_BYTE_COUNT(message_len);
9481         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9482             TRUE);
9483         COUNT_BYTES(message_len);
9484
9485         END_OF_SMB
9486
9487         return offset;
9488 }
9489
9490 static int
9491 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9492 {
9493         int name_len;
9494         guint16 bc;
9495         guint8 wc;
9496
9497         WORD_COUNT;
9498
9499         BYTE_COUNT;
9500
9501         /* buffer format */
9502         CHECK_BYTE_COUNT(1);
9503         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9504         COUNT_BYTES(1);
9505
9506         /* originator name */
9507         /* XXX - what if this runs past bc? */
9508         name_len = tvb_strsize(tvb, offset);
9509         CHECK_BYTE_COUNT(name_len);
9510         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9511             name_len, TRUE);
9512         COUNT_BYTES(name_len);
9513
9514         /* buffer format */
9515         CHECK_BYTE_COUNT(1);
9516         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9517         COUNT_BYTES(1);
9518
9519         /* destination name */
9520         /* XXX - what if this runs past bc? */
9521         name_len = tvb_strsize(tvb, offset);
9522         CHECK_BYTE_COUNT(name_len);
9523         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9524             name_len, TRUE);
9525         COUNT_BYTES(name_len);
9526
9527         END_OF_SMB
9528
9529         return offset;
9530 }
9531
9532 static int
9533 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9534 {
9535         guint16 bc;
9536         guint8 wc;
9537
9538         WORD_COUNT;
9539
9540         /* message group ID */
9541         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9542         offset += 2;
9543
9544         BYTE_COUNT;
9545
9546         END_OF_SMB
9547
9548         return offset;
9549 }
9550
9551 static int
9552 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9553 {
9554         guint16 bc;
9555         guint8 wc;
9556         guint16 message_len;
9557
9558         WORD_COUNT;
9559
9560         BYTE_COUNT;
9561
9562         /* buffer format */
9563         CHECK_BYTE_COUNT(1);
9564         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9565         COUNT_BYTES(1);
9566
9567         /* message len */
9568         CHECK_BYTE_COUNT(2);
9569         message_len = tvb_get_letohs(tvb, offset);
9570         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9571             message_len);
9572         COUNT_BYTES(2);
9573
9574         /* message */
9575         CHECK_BYTE_COUNT(message_len);
9576         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9577             TRUE);
9578         COUNT_BYTES(message_len);
9579
9580         END_OF_SMB
9581
9582         return offset;
9583 }
9584
9585 static int
9586 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9587 {
9588         int name_len;
9589         guint16 bc;
9590         guint8 wc;
9591
9592         WORD_COUNT;
9593
9594         BYTE_COUNT;
9595
9596         /* buffer format */
9597         CHECK_BYTE_COUNT(1);
9598         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9599         COUNT_BYTES(1);
9600
9601         /* forwarded name */
9602         /* XXX - what if this runs past bc? */
9603         name_len = tvb_strsize(tvb, offset);
9604         CHECK_BYTE_COUNT(name_len);
9605         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9606             name_len, TRUE);
9607         COUNT_BYTES(name_len);
9608
9609         END_OF_SMB
9610
9611         return offset;
9612 }
9613
9614 static int
9615 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9616 {
9617         int name_len;
9618         guint16 bc;
9619         guint8 wc;
9620
9621         WORD_COUNT;
9622
9623         BYTE_COUNT;
9624
9625         /* buffer format */
9626         CHECK_BYTE_COUNT(1);
9627         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9628         COUNT_BYTES(1);
9629
9630         /* machine name */
9631         /* XXX - what if this runs past bc? */
9632         name_len = tvb_strsize(tvb, offset);
9633         CHECK_BYTE_COUNT(name_len);
9634         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9635             name_len, TRUE);
9636         COUNT_BYTES(name_len);
9637
9638         END_OF_SMB
9639
9640         return offset;
9641 }
9642
9643
9644 static int
9645 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9646 {
9647         guint8  wc, cmd=0xff;
9648         guint16 andxoffset=0;
9649         guint16 bc;
9650         smb_info_t *si = pinfo->private_data;
9651         int fn_len;
9652         const char *fn;
9653         guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0, create_disposition=0;
9654
9655         DISSECTOR_ASSERT(si);
9656
9657         WORD_COUNT;
9658
9659         /* next smb command */
9660         cmd = tvb_get_guint8(tvb, offset);
9661         if(cmd!=0xff){
9662                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9663         } else {
9664                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9665         }
9666         offset += 1;
9667
9668         /* reserved byte */
9669         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9670         offset += 1;
9671
9672         /* andxoffset */
9673         andxoffset = tvb_get_letohs(tvb, offset);
9674         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9675         offset += 2;
9676
9677         /* reserved byte */
9678         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9679         offset += 1;
9680
9681         /* file name len */
9682         fn_len = tvb_get_letohs(tvb, offset);
9683         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9684         offset += 2;
9685
9686         /* Create flags */
9687         create_flags=tvb_get_letohl(tvb, offset);
9688         offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
9689
9690         /* root directory fid */
9691         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9692         offset += 4;
9693
9694         /* nt access mask */
9695         access_mask=tvb_get_letohl(tvb, offset);
9696         offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
9697
9698         /* allocation size */
9699         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9700         offset += 8;
9701
9702         /* Extended File Attributes */
9703         file_attributes=tvb_get_letohl(tvb, offset);
9704         offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
9705
9706         /* share access */
9707         share_access=tvb_get_letohl(tvb, offset);
9708         offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
9709
9710         /* create disposition */
9711         create_disposition=tvb_get_letohl(tvb, offset);
9712         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9713         offset += 4;
9714
9715         /* create options */
9716         create_options=tvb_get_letohl(tvb, offset);
9717         offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
9718
9719         /* impersonation level */
9720         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9721         offset += 4;
9722
9723         /* security flags */
9724         offset = dissect_nt_security_flags(tvb, tree, offset);
9725
9726         BYTE_COUNT;
9727
9728         /* file name */
9729         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9730         if (fn == NULL)
9731                 goto endofcommand;
9732         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9733                 fn);
9734         COUNT_BYTES(fn_len);
9735
9736         /* store it for the fid->name/openframe/closeframe matching in
9737          * dissect_smb_fid()   called from the response.
9738          */
9739         if((!pinfo->fd->flags.visited) && si->sip && fn){
9740                 smb_fid_saved_info_t *fsi;
9741
9742                 fsi=se_alloc(sizeof(smb_fid_saved_info_t));
9743                 fsi->filename=se_strdup(fn);
9744                 fsi->create_flags=create_flags;
9745                 fsi->access_mask=access_mask;
9746                 fsi->file_attributes=file_attributes;
9747                 fsi->share_access=share_access;
9748                 fsi->create_options=create_options;
9749                 fsi->create_disposition=create_disposition;
9750
9751                 si->sip->extra_info_type=SMB_EI_FILEDATA;
9752                 si->sip->extra_info=fsi;
9753         }
9754
9755         if (check_col(pinfo->cinfo, COL_INFO)) {
9756                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9757                     format_text(fn, strlen(fn)));
9758         }
9759
9760         END_OF_SMB
9761
9762         if (cmd != 0xff) {      /* there is an andX command */
9763                 if (andxoffset < offset)
9764                         THROW(ReportedBoundsError);
9765                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9766         }
9767
9768         return offset;
9769 }
9770
9771
9772 static int
9773 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9774 {
9775         guint8  wc, cmd=0xff;
9776         guint16 andxoffset=0;
9777         guint16 bc;
9778         guint16 fid=0;
9779         guint16 ftype;
9780         guint8  isdir;
9781         smb_fid_info_t *fid_info=NULL;
9782         smb_info_t              *si;
9783
9784         si = pinfo->private_data;
9785
9786         WORD_COUNT;
9787
9788         /* next smb command */
9789         cmd = tvb_get_guint8(tvb, offset);
9790         if(cmd!=0xff){
9791                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9792         } else {
9793                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9794         }
9795         offset += 1;
9796
9797         /* reserved byte */
9798         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9799         offset += 1;
9800
9801         /* andxoffset */
9802         andxoffset = tvb_get_letohs(tvb, offset);
9803         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9804         offset += 2;
9805
9806         /* oplock level */
9807         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9808         offset += 1;
9809
9810         /* fid */
9811         fid = tvb_get_letohs(tvb, offset);
9812         fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
9813         offset += 2;
9814
9815         /* create action */
9816         /*XXX is this really the same as create disposition in the request? it looks so*/
9817         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9818         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9819         offset += 4;
9820
9821         /* create time */
9822         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
9823
9824         /* access time */
9825         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
9826
9827         /* last write time */
9828         offset = dissect_nt_64bit_time(tvb, tree, offset,
9829                 hf_smb_last_write_time);
9830
9831         /* last change time */
9832         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
9833
9834         /* Extended File Attributes */
9835         offset = dissect_file_ext_attr(tvb, tree, offset);
9836
9837         /* allocation size */
9838         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9839         offset += 8;
9840
9841         /* end of file */
9842         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9843         offset += 8;
9844
9845         /* File Type */
9846         ftype=tvb_get_letohs(tvb, offset);
9847         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9848         offset += 2;
9849
9850         /* IPC State */
9851         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9852
9853         /* is directory */
9854         isdir=tvb_get_guint8(tvb, offset);
9855         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9856         offset += 1;
9857
9858         /* Try to remember the type of this fid so that we can dissect
9859          * any future security descriptor (access mask) properly
9860          */
9861         if(ftype==0){
9862                 if(isdir==0){
9863                         if(fid_info){
9864                                 fid_info->type=SMB_FID_TYPE_FILE;
9865                         }
9866                 } else {
9867                         if(fid_info){
9868                                 fid_info->type=SMB_FID_TYPE_DIR;
9869                         }
9870                 }
9871         }
9872         if(ftype==2){
9873                 if(fid_info){
9874                         fid_info->type=SMB_FID_TYPE_PIPE;
9875                 }
9876         }               
9877
9878         BYTE_COUNT;
9879
9880         END_OF_SMB
9881
9882         if (cmd != 0xff) {      /* there is an andX command */
9883                 if (andxoffset < offset)
9884                         THROW(ReportedBoundsError);
9885                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9886         }
9887
9888         /* if there was an error, add a generated filename to the tree */
9889         if(si->nt_status){
9890                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
9891         }
9892
9893         return offset;
9894 }
9895
9896
9897 static int
9898 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9899 {
9900         guint8 wc;
9901         guint16 bc;
9902
9903         WORD_COUNT;
9904
9905         BYTE_COUNT;
9906
9907         END_OF_SMB
9908
9909         return offset;
9910 }
9911
9912 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9913    BEGIN Transaction/Transaction2 Primary and secondary requests
9914    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9915
9916
9917 const value_string trans2_cmd_vals[] = {
9918         { 0x00,         "OPEN2" },
9919         { 0x01,         "FIND_FIRST2" },
9920         { 0x02,         "FIND_NEXT2" },
9921         { 0x03,         "QUERY_FS_INFO" },
9922         { 0x04,         "SET_FS_QUOTA" },
9923         { 0x05,         "QUERY_PATH_INFO" },
9924         { 0x06,         "SET_PATH_INFO" },
9925         { 0x07,         "QUERY_FILE_INFO" },
9926         { 0x08,         "SET_FILE_INFO" },
9927         { 0x09,         "FSCTL" },
9928         { 0x0A,         "IOCTL2" },
9929         { 0x0B,         "FIND_NOTIFY_FIRST" },
9930         { 0x0C,         "FIND_NOTIFY_NEXT" },
9931         { 0x0D,         "CREATE_DIRECTORY" },
9932         { 0x0E,         "SESSION_SETUP" },
9933         { 0x10,         "GET_DFS_REFERRAL" },
9934         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9935         { 0,    NULL }
9936 };
9937
9938 static const true_false_string tfs_tf_dtid = {
9939         "Also DISCONNECT TID",
9940         "Do NOT disconnect TID"
9941 };
9942 static const true_false_string tfs_tf_owt = {
9943         "One Way Transaction (NO RESPONSE)",
9944         "Two way transaction"
9945 };
9946
9947 static const true_false_string tfs_ff2_backup = {
9948         "Find WITH backup intent",
9949         "No backup intent"
9950 };
9951 static const true_false_string tfs_ff2_continue = {
9952         "CONTINUE search from previous position",
9953         "New search, do NOT continue from previous position"
9954 };
9955 static const true_false_string tfs_ff2_resume = {
9956         "Return RESUME keys",
9957         "Do NOT return resume keys"
9958 };
9959 static const true_false_string tfs_ff2_close_eos = {
9960         "CLOSE search if END OF SEARCH is reached",
9961         "Do NOT close search if end of search reached"
9962 };
9963 static const true_false_string tfs_ff2_close = {
9964         "CLOSE search after this request",
9965         "Do NOT close search after this request"
9966 };
9967
9968 /* used by
9969    TRANS2_FIND_FIRST2
9970 */
9971 static const value_string ff2_il_vals[] = {
9972         { 1,            "Info Standard"},
9973         { 2,            "Info Query EA Size"},
9974         { 3,            "Info Query EAs From List"},
9975         { 0x0101,       "Find File Directory Info"},
9976         { 0x0102,       "Find File Full Directory Info"},
9977         { 0x0103,       "Find File Names Info"},
9978         { 0x0104,       "Find File Both Directory Info"},
9979         { 0x0202,       "Find File UNIX"},
9980         {0, NULL}
9981 };
9982
9983 /* values used by :
9984         TRANS2_QUERY_PATH_INFORMATION
9985         TRANS2_QUERY_FILE_INFORMATION
9986 */
9987 static const value_string qpi_loi_vals[] = {
9988         { 1,            "Info Standard"},
9989         { 2,            "Info Query EA Size"},
9990         { 3,            "Info Query EAs From List"},
9991         { 4,            "Info Query All EAs"},
9992         { 6,            "Info Is Name Valid"},
9993         { 0x0101,       "Query File Basic Info"},
9994         { 0x0102,       "Query File Standard Info"},
9995         { 0x0103,       "Query File EA Info"},
9996         { 0x0104,       "Query File Name Info"},
9997         { 0x0107,       "Query File All Info"},
9998         { 0x0108,       "Query File Alt Name Info"},
9999         { 0x0109,       "Query File Stream Info"},
10000         { 0x010b,       "Query File Compression Info"},
10001         { 0x0200,       "Query File Unix Basic"},
10002         { 0x0201,       "Query File Unix Link"},
10003         { 1004,         "Query File Basic Info"},
10004         { 1005,         "Query File Standard Info"},
10005         { 1006,         "Query File Internal Info"},
10006         { 1007,         "Query File EA Info"},
10007         { 1009,         "Query File Name Info"},
10008         { 1010,         "Query File Rename Info"},
10009         { 1011,         "Query File Link Info"},
10010         { 1012,         "Query File Names Info"},
10011         { 1013,         "Query File Disposition Info"},
10012         { 1014,         "Query File Position Info"},
10013         { 1015,         "Query File Full EA Info"},
10014         { 1016,         "Query File Mode Info"},
10015         { 1017,         "Query File Alignment Info"},
10016         { 1018,         "Query File All Info"},
10017         { 1019,         "Query File Allocation Info"},
10018         { 1020,         "Query File End of File Info"},
10019         { 1021,         "Query File Alt Name Info"},
10020         { 1022,         "Query File Stream Info"},
10021         { 1023,         "Query File Pipe Info"},
10022         { 1024,         "Query File Pipe Local Info"},
10023         { 1025,         "Query File Pipe Remote Info"},
10024         { 1026,         "Query File Mailslot Query Info"},
10025         { 1027,         "Query File Mailslot Set Info"},
10026         { 1028,         "Query File Compression Info"},
10027         { 1029,         "Query File ObjectID Info"},
10028         { 1030,         "Query File Completion Info"},
10029         { 1031,         "Query File Move Cluster Info"},
10030         { 1032,         "Query File Quota Info"},
10031         { 1033,         "Query File Reparsepoint Info"},
10032         { 1034,         "Query File Network Open Info"},
10033         { 1035,         "Query File Attribute Tag Info"},
10034         { 1036,         "Query File Tracking Info"},
10035         { 1037,         "Query File Maximum Info"},
10036         {0, NULL}
10037 };
10038
10039 /* values used by :
10040         TRANS2_SET_PATH_INFORMATION
10041         TRANS2_SET_FILE_INFORMATION
10042         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10043         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10044         well; note that they're different from the QUERY_PATH_INFORMATION
10045         and QUERY_FILE_INFORMATION values!)
10046 */
10047 static const value_string spi_loi_vals[] = {
10048         { 1,            "Info Standard"},
10049         { 2,            "Info Query EA Size"},
10050         { 4,            "Info Query All EAs"},
10051         { 0x0101,       "Set File Basic Info"},
10052         { 0x0102,       "Set File Disposition Info"},
10053         { 0x0103,       "Set File Allocation Info"},
10054         { 0x0104,       "Set File End Of File Info"},
10055         { 0x0200,       "Set File Unix Basic"},
10056         { 0x0201,       "Set File Unix Link"},
10057         { 0x0202,       "Set File Unix HardLink"},
10058         { 1004,         "Set File Basic Info"},
10059         { 1010,         "Set Rename Information"},
10060         { 1013,         "Set Disposition Information"},
10061         { 1014,         "Set Position Information"},
10062         { 1016,         "Set Mode Information"},
10063         { 1019,         "Set Allocation Information"},
10064         { 1020,         "Set EOF Information"},
10065         { 1023,         "Set File Pipe Information"},
10066         { 1025,         "Set File Pipe Remote Information"},
10067         { 1029,         "Set Copy On Write Information"},
10068         { 1032,         "Set OLE Class ID Information"},
10069         { 1039,         "Set Inherit Context Index Information"},
10070         { 1040,         "Set OLE Information (?)"},
10071         {0, NULL}
10072 };
10073
10074 static const value_string qfsi_vals[] = {
10075         { 1,            "Info Allocation"},
10076         { 2,            "Info Volume"},
10077         { 0x0101,       "Query FS Label Info"},
10078         { 0x0102,       "Query FS Volume Info"},
10079         { 0x0103,       "Query FS Size Info"},
10080         { 0x0104,       "Query FS Device Info"},
10081         { 0x0105,       "Query FS Attribute Info"},
10082         { 0x0200,       "Unix Query FS Info"},
10083         { 0x0301,       "Mac Query FS Info"},
10084         { 1001,         "Query FS Label Info"},
10085         { 1002,         "Query FS Volume Info"},
10086         { 1003,         "Query FS Size Info"},
10087         { 1004,         "Query FS Device Info"},
10088         { 1005,         "Query FS Attribute Info"},
10089         { 1006,         "Query FS Quota Info"},
10090         { 1007,         "Query Full FS Size Info"},
10091         { 1008,         "Object ID Information"},
10092         {0, NULL}
10093 };
10094
10095 static const value_string nt_rename_vals[] = {
10096         { 0x0103,       "Create Hard Link"},
10097         {0, NULL}
10098 };
10099
10100
10101 static const value_string delete_pending_vals[] = {
10102         {0,     "Normal, no pending delete"},
10103         {1,     "This object has DELETE PENDING"},
10104         {0, NULL}
10105 };
10106
10107 static const value_string alignment_vals[] = {
10108         {0,     "Byte alignment"},
10109         {1,     "Word (16bit) alignment"},
10110         {3,     "Long (32bit) alignment"},
10111         {7,     "8 byte boundary alignment"},
10112         {0x0f,  "16 byte boundary alignment"},
10113         {0x1f,  "32 byte boundary alignment"},
10114         {0x3f,  "64 byte boundary alignment"},
10115         {0x7f,  "128 byte boundary alignment"},
10116         {0xff,  "256 byte boundary alignment"},
10117         {0x1ff, "512 byte boundary alignment"},
10118         {0, NULL}
10119 };
10120
10121 static const true_false_string tfs_marked_for_deletion = {
10122         "File is MARKED FOR DELETION",
10123         "File is NOT marked for deletion"
10124 };
10125
10126 static const true_false_string tfs_get_dfs_server_hold_storage = {
10127         "Referral SERVER HOLDS STORAGE for the file",
10128         "Referral server does NOT hold storage for the file"
10129 };
10130 static const true_false_string tfs_get_dfs_fielding = {
10131         "The server in referral is FIELDING CAPABLE",
10132         "The server in referrals is NOT fielding capable"
10133 };
10134
10135 static const true_false_string tfs_dfs_referral_flags_strip = {
10136         "STRIP off pathconsumed characters before submitting",
10137         "Do NOT strip off any characters"
10138 };
10139
10140 static const value_string dfs_referral_server_type_vals[] = {
10141         {0,     "Don't know"},
10142         {1,     "SMB Server"},
10143         {2,     "Netware Server"},
10144         {3,     "Domain Server"},
10145         {0, NULL}
10146 };
10147
10148
10149 static const true_false_string tfs_device_char_removable = {
10150         "This is a REMOVABLE device",
10151         "This is NOT a removable device"
10152 };
10153 static const true_false_string tfs_device_char_read_only = {
10154         "This is a READ-ONLY device",
10155         "This is NOT a read-only device"
10156 };
10157 static const true_false_string tfs_device_char_floppy = {
10158         "This is a FLOPPY DISK device",
10159         "This is NOT a floppy disk device"
10160 };
10161 static const true_false_string tfs_device_char_write_once = {
10162         "This is a WRITE-ONCE device",
10163         "This is NOT a write-once device"
10164 };
10165 static const true_false_string tfs_device_char_remote = {
10166         "This is a REMOTE device",
10167         "This is NOT a remote device"
10168 };
10169 static const true_false_string tfs_device_char_mounted = {
10170         "This device is MOUNTED",
10171         "This device is NOT mounted"
10172 };
10173 static const true_false_string tfs_device_char_virtual = {
10174         "This is a VIRTUAL device",
10175         "This is NOT a virtual device"
10176 };
10177
10178
10179 static const true_false_string tfs_fs_attr_css = {
10180         "This FS supports CASE SENSITIVE SEARCHes",
10181         "This FS does NOT support case sensitive searches"
10182 };
10183 static const true_false_string tfs_fs_attr_cpn = {
10184         "This FS supports CASE PRESERVED NAMES",
10185         "This FS does NOT support case preserved names"
10186 };
10187 static const true_false_string tfs_fs_attr_uod = {
10188         "This FS supports UNICODE NAMES",
10189         "This FS does NOT support unicode names"
10190 };
10191 static const true_false_string tfs_fs_attr_pacls = {
10192         "This FS supports PERSISTENT ACLs",
10193         "This FS does NOT support persistent acls"
10194 };
10195 static const true_false_string tfs_fs_attr_fc = {
10196         "This FS supports COMPRESSED FILES",
10197         "This FS does NOT support compressed files"
10198 };
10199 static const true_false_string tfs_fs_attr_vq = {
10200         "This FS supports VOLUME QUOTAS",
10201         "This FS does NOT support volume quotas"
10202 };
10203 static const true_false_string tfs_fs_attr_srp = {
10204         "This FS supports REPARSE POINTS",
10205         "This FS does NOT support reparse points"
10206 };
10207 static const true_false_string tfs_fs_attr_srs = {
10208         "This FS supports REMOTE STORAGE",
10209         "This FS does NOT support remote storage"
10210 };
10211 static const true_false_string tfs_fs_attr_ssf = {
10212         "This FS supports SPARSE FILES",
10213         "This FS does NOT support sparse files"
10214 };
10215 static const true_false_string tfs_fs_attr_sla = {
10216         "This FS supports LFN APIs",
10217         "This FS does NOT support lfn apis"
10218 };
10219 static const true_false_string tfs_fs_attr_vic = {
10220         "This FS VOLUME IS COMPRESSED",
10221         "This FS volume is NOT compressed"
10222 };
10223 static const true_false_string tfs_fs_attr_soids = {
10224         "This FS supports OIDs",
10225         "This FS does NOT support OIDs"
10226 };
10227 static const true_false_string tfs_fs_attr_se = {
10228         "This FS supports ENCRYPTION",
10229         "This FS does NOT support encryption"
10230 };
10231 static const true_false_string tfs_fs_attr_ns = {
10232         "This FS supports NAMED STREAMS",
10233         "This FS does NOT support named streams"
10234 };
10235 static const true_false_string tfs_fs_attr_rov = {
10236         "This is a READ ONLY VOLUME",
10237         "This is a read/write volume"
10238 };
10239
10240 #define FF2_RESUME      0x0004
10241
10242 static int
10243 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10244 {
10245         guint16 mask;
10246         proto_item *item = NULL;
10247         proto_tree *tree = NULL;
10248         smb_info_t *si;
10249         smb_transact2_info_t *t2i;
10250
10251         mask = tvb_get_letohs(tvb, offset);
10252
10253         si = (smb_info_t *)pinfo->private_data;
10254         DISSECTOR_ASSERT(si);
10255
10256         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
10257                 t2i = si->sip->extra_info;
10258                 if (t2i != NULL) {
10259                         if (!pinfo->fd->flags.visited)
10260                                 t2i->resume_keys = (mask & FF2_RESUME);
10261                 }
10262         }
10263
10264         if(parent_tree){
10265                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10266                         "Flags: 0x%04x", mask);
10267                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10268         }
10269
10270         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10271                 tvb, offset, 2, mask);
10272         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10273                 tvb, offset, 2, mask);
10274         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10275                 tvb, offset, 2, mask);
10276         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10277                 tvb, offset, 2, mask);
10278         proto_tree_add_boolean(tree, hf_smb_ff2_close,
10279                 tvb, offset, 2, mask);
10280
10281         offset += 2;
10282
10283         return offset;
10284 }
10285
10286 #if 0
10287 static int
10288 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10289 {
10290         guint16 mask;
10291         proto_item *item = NULL;
10292         proto_tree *tree = NULL;
10293
10294         mask = tvb_get_letohs(tvb, offset);
10295
10296         if(parent_tree){
10297                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10298                         "IO Flag: 0x%04x", mask);
10299                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10300         }
10301
10302         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10303                 tvb, offset, 2, mask);
10304         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10305                 tvb, offset, 2, mask);
10306
10307         offset += 2;
10308
10309         return offset;
10310 }
10311 #endif
10312
10313 static int
10314 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10315     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10316 {
10317         proto_item *item = NULL;
10318         proto_tree *tree = NULL;
10319         smb_info_t *si;
10320         smb_transact2_info_t *t2i;
10321         int fn_len;
10322         const char *fn;
10323
10324         si = (smb_info_t *)pinfo->private_data;
10325         DISSECTOR_ASSERT(si);
10326
10327         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
10328                 t2i = si->sip->extra_info;
10329         else
10330                 t2i = NULL;
10331
10332         if(parent_tree){
10333                 tvb_ensure_bytes_exist(tvb, offset, bc);
10334                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10335                                 "%s Parameters",
10336                                 val_to_str(subcmd, trans2_cmd_vals,
10337                                            "Unknown (0x%02x)"));
10338                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10339         }
10340
10341         switch(subcmd){
10342         case 0x00:      /*TRANS2_OPEN2*/
10343                 /* open flags */
10344                 CHECK_BYTE_COUNT_TRANS(2);
10345                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10346                 bc -= 2;
10347
10348                 /* desired access */
10349                 CHECK_BYTE_COUNT_TRANS(2);
10350                 offset = dissect_access(tvb, tree, offset, "Desired");
10351                 bc -= 2;
10352
10353                 /* Search Attributes */
10354                 CHECK_BYTE_COUNT_TRANS(2);
10355                 offset = dissect_search_attributes(tvb, tree, offset);
10356                 bc -= 2;
10357
10358                 /* File Attributes */
10359                 CHECK_BYTE_COUNT_TRANS(2);
10360                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10361                 bc -= 2;
10362
10363                 /* create time */
10364                 CHECK_BYTE_COUNT_TRANS(4);
10365                 offset = dissect_smb_datetime(tvb, tree, offset,
10366                         hf_smb_create_time,
10367                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10368                         TRUE);
10369                 bc -= 4;
10370
10371                 /* open function */
10372                 CHECK_BYTE_COUNT_TRANS(2);
10373                 offset = dissect_open_function(tvb, tree, offset);
10374                 bc -= 2;
10375
10376                 /* allocation size */
10377                 CHECK_BYTE_COUNT_TRANS(4);
10378                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10379                 COUNT_BYTES_TRANS(4);
10380
10381                 /* 10 reserved bytes */
10382                 CHECK_BYTE_COUNT_TRANS(10);
10383                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10384                 COUNT_BYTES_TRANS(10);
10385
10386                 /* file name */
10387                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10388                 CHECK_STRING_TRANS(fn);
10389                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10390                         fn);
10391                 COUNT_BYTES_TRANS(fn_len);
10392
10393                 if (check_col(pinfo->cinfo, COL_INFO)) {
10394                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10395                             format_text(fn, strlen(fn)));
10396                 }
10397                 break;
10398         case 0x01:      /*TRANS2_FIND_FIRST2*/
10399                 /* Search Attributes */
10400                 CHECK_BYTE_COUNT_TRANS(2);
10401                 offset = dissect_search_attributes(tvb, tree, offset);
10402                 bc -= 2;
10403
10404                 /* search count */
10405                 CHECK_BYTE_COUNT_TRANS(2);
10406                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10407                 COUNT_BYTES_TRANS(2);
10408
10409                 /* Find First2 flags */
10410                 CHECK_BYTE_COUNT_TRANS(2);
10411                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10412                 bc -= 2;
10413
10414                 /* Find First2 information level */
10415                 CHECK_BYTE_COUNT_TRANS(2);
10416                 si->info_level = tvb_get_letohs(tvb, offset);
10417                 if (t2i != NULL && !pinfo->fd->flags.visited)
10418                         t2i->info_level = si->info_level;
10419                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10420                 COUNT_BYTES_TRANS(2);
10421
10422                 /* storage type */
10423                 CHECK_BYTE_COUNT_TRANS(4);
10424                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10425                 COUNT_BYTES_TRANS(4);
10426
10427                 /* search pattern */
10428                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10429                 CHECK_STRING_TRANS(fn);
10430                 if(!t2i->name){
10431                         t2i->name = se_strdup(fn);
10432                 }
10433                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10434                         fn);
10435                 COUNT_BYTES_TRANS(fn_len);
10436
10437                 if (check_col(pinfo->cinfo, COL_INFO)) {
10438                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10439                             format_text(fn, strlen(fn)));
10440                 }
10441
10442                 break;
10443         case 0x02:      /*TRANS2_FIND_NEXT2*/
10444                 /* sid */
10445                 CHECK_BYTE_COUNT_TRANS(2);
10446                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10447                 COUNT_BYTES_TRANS(2);
10448
10449                 /* search count */
10450                 CHECK_BYTE_COUNT_TRANS(2);
10451                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10452                 COUNT_BYTES_TRANS(2);
10453
10454                 /* Find First2 information level */
10455                 CHECK_BYTE_COUNT_TRANS(2);
10456                 si->info_level = tvb_get_letohs(tvb, offset);
10457                 if (t2i != NULL && !pinfo->fd->flags.visited)
10458                         t2i->info_level = si->info_level;
10459                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10460                 COUNT_BYTES_TRANS(2);
10461
10462                 /* resume key */
10463                 CHECK_BYTE_COUNT_TRANS(4);
10464                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10465                 COUNT_BYTES_TRANS(4);
10466
10467                 /* Find First2 flags */
10468                 CHECK_BYTE_COUNT_TRANS(2);
10469                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10470                 bc -= 2;
10471
10472                 /* file name */
10473                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10474                 CHECK_STRING_TRANS(fn);
10475                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10476                         fn);
10477                 COUNT_BYTES_TRANS(fn_len);
10478
10479                 if (check_col(pinfo->cinfo, COL_INFO)) {
10480                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10481                             format_text(fn, strlen(fn)));
10482                 }
10483
10484                 break;
10485         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10486                 /* level of interest */
10487                 CHECK_BYTE_COUNT_TRANS(2);
10488                 si->info_level = tvb_get_letohs(tvb, offset);
10489                 if (t2i != NULL && !pinfo->fd->flags.visited)
10490                         t2i->info_level = si->info_level;
10491                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10492                 COUNT_BYTES_TRANS(2);
10493
10494                 if (check_col(pinfo->cinfo, COL_INFO))
10495                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10496                                         val_to_str(si->info_level, qfsi_vals, 
10497                                                    "Unknown (0x%02x)"));
10498
10499                 break;
10500         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10501                 /* level of interest */
10502                 CHECK_BYTE_COUNT_TRANS(2);
10503                 si->info_level = tvb_get_letohs(tvb, offset);
10504                 if (t2i != NULL && !pinfo->fd->flags.visited)
10505                         t2i->info_level = si->info_level;
10506                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10507                 COUNT_BYTES_TRANS(2);
10508
10509                 if (check_col(pinfo->cinfo, COL_INFO)) {
10510                         col_append_fstr(
10511                                 pinfo->cinfo, COL_INFO, ", %s", 
10512                                 val_to_str(si->info_level, qpi_loi_vals, 
10513                                            "Unknown (%u)"));
10514                 }
10515
10516                 /* 4 reserved bytes */
10517                 CHECK_BYTE_COUNT_TRANS(4);
10518                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10519                 COUNT_BYTES_TRANS(4);
10520
10521                 /* file name */
10522                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10523                 CHECK_STRING_TRANS(fn);
10524                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10525                         fn);
10526                 COUNT_BYTES_TRANS(fn_len);
10527                 if(!t2i->name){
10528                         t2i->name = se_strdup(fn);
10529                 }
10530
10531                 if (check_col(pinfo->cinfo, COL_INFO)) {
10532                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10533                             format_text(fn, strlen(fn)));
10534                 }
10535
10536                 break;
10537         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10538                 /* level of interest */
10539                 CHECK_BYTE_COUNT_TRANS(2);
10540                 si->info_level = tvb_get_letohs(tvb, offset);
10541                 if (t2i != NULL && !pinfo->fd->flags.visited)
10542                         t2i->info_level = si->info_level;
10543                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10544                 COUNT_BYTES_TRANS(2);
10545
10546                 /* 4 reserved bytes */
10547                 CHECK_BYTE_COUNT_TRANS(4);
10548                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10549                 COUNT_BYTES_TRANS(4);
10550
10551                 /* file name */
10552                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10553                 CHECK_STRING_TRANS(fn);
10554                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10555                         fn);
10556                 COUNT_BYTES_TRANS(fn_len);
10557
10558                 if (check_col(pinfo->cinfo, COL_INFO)) {
10559                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10560                             format_text(fn, strlen(fn)));
10561                 }
10562
10563                 break;
10564         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10565                 guint16 fid;
10566
10567                 /* fid */
10568                 CHECK_BYTE_COUNT_TRANS(2);
10569                 fid = tvb_get_letohs(tvb, offset);
10570                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10571                 COUNT_BYTES_TRANS(2);
10572
10573                 /* level of interest */
10574                 CHECK_BYTE_COUNT_TRANS(2);
10575                 si->info_level = tvb_get_letohs(tvb, offset);
10576                 if (t2i != NULL && !pinfo->fd->flags.visited)
10577                         t2i->info_level = si->info_level;
10578                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10579                 COUNT_BYTES_TRANS(2);
10580
10581                 if (check_col(pinfo->cinfo, COL_INFO)) {
10582                         col_append_fstr(
10583                                 pinfo->cinfo, COL_INFO, ", %s", 
10584                                 val_to_str(si->info_level, qpi_loi_vals, 
10585                                            "Unknown (%u)"));
10586                 }
10587
10588                 break;
10589         }
10590         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10591                 guint16 fid;
10592
10593                 /* fid */
10594                 CHECK_BYTE_COUNT_TRANS(2);
10595                 fid = tvb_get_letohs(tvb, offset);
10596                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10597                 COUNT_BYTES_TRANS(2);
10598
10599                 /* level of interest */
10600                 CHECK_BYTE_COUNT_TRANS(2);
10601                 si->info_level = tvb_get_letohs(tvb, offset);
10602                 if (t2i != NULL && !pinfo->fd->flags.visited)
10603                         t2i->info_level = si->info_level;
10604                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10605                 COUNT_BYTES_TRANS(2);
10606
10607 #if 0
10608                 /*
10609                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10610                  * Extensions Version 3.0, Document Version 1.11,
10611                  * July 19, 1990" says this is I/O flags, but it's
10612                  * reserved in the SNIA spec, and some clients appear
10613                  * to leave junk in it.
10614                  *
10615                  * Is this some field used only if a particular
10616                  * dialect was negotiated, so that clients can feel
10617                  * safe not setting it if they haven't negotiated that
10618                  * dialect?  Or do the (non-OS/2) clients simply not care
10619                  * about that particular OS/2-oriented dialect?
10620                  */
10621
10622                 /* IO Flag */
10623                 CHECK_BYTE_COUNT_TRANS(2);
10624                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10625                 bc -= 2;
10626 #else
10627                 /* 2 reserved bytes */
10628                 CHECK_BYTE_COUNT_TRANS(2);
10629                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10630                 COUNT_BYTES_TRANS(2);
10631 #endif
10632
10633                 break;
10634         }
10635         case 0x09:      /*TRANS2_FSCTL*/
10636                 /* this call has no parameter block in the request */
10637
10638                 /*
10639                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10640                  * Extensions Version 3.0, Document Version 1.11,
10641                  * July 19, 1990" says this this contains a
10642                  * "File system specific parameter block".  (That means
10643                  * we may not be able to dissect it in any case.)
10644                  */
10645                 break;
10646         case 0x0a:      /*TRANS2_IOCTL2*/
10647                 /* this call has no parameter block in the request */
10648
10649                 /*
10650                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10651                  * Extensions Version 3.0, Document Version 1.11,
10652                  * July 19, 1990" says this this contains a
10653                  * "Device/function specific parameter block".  (That
10654                  * means we may not be able to dissect it in any case.)
10655                  */
10656                 break;
10657         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10658                 /* Search Attributes */
10659                 CHECK_BYTE_COUNT_TRANS(2);
10660                 offset = dissect_search_attributes(tvb, tree, offset);
10661                 bc -= 2;
10662
10663                 /* Number of changes to wait for */
10664                 CHECK_BYTE_COUNT_TRANS(2);
10665                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10666                 COUNT_BYTES_TRANS(2);
10667
10668                 /* Find Notify information level */
10669                 CHECK_BYTE_COUNT_TRANS(2);
10670                 si->info_level = tvb_get_letohs(tvb, offset);
10671                 if (t2i != NULL && !pinfo->fd->flags.visited)
10672                         t2i->info_level = si->info_level;
10673                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10674                 COUNT_BYTES_TRANS(2);
10675
10676                 /* 4 reserved bytes */
10677                 CHECK_BYTE_COUNT_TRANS(4);
10678                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10679                 COUNT_BYTES_TRANS(4);
10680
10681                 /* file name */
10682                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10683                 CHECK_STRING_TRANS(fn);
10684                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10685                         fn);
10686                 COUNT_BYTES_TRANS(fn_len);
10687
10688                 if (check_col(pinfo->cinfo, COL_INFO)) {
10689                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10690                             format_text(fn, strlen(fn)));
10691                 }
10692
10693                 break;
10694         }
10695         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10696                 /* Monitor handle */
10697                 CHECK_BYTE_COUNT_TRANS(2);
10698                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10699                 COUNT_BYTES_TRANS(2);
10700
10701                 /* Number of changes to wait for */
10702                 CHECK_BYTE_COUNT_TRANS(2);
10703                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10704                 COUNT_BYTES_TRANS(2);
10705
10706                 break;
10707         }
10708         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10709                 /* 4 reserved bytes */
10710                 CHECK_BYTE_COUNT_TRANS(4);
10711                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10712                 COUNT_BYTES_TRANS(4);
10713
10714                 /* dir name */
10715                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10716                         FALSE, FALSE, &bc);
10717                 CHECK_STRING_TRANS(fn);
10718                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10719                         fn);
10720                 COUNT_BYTES_TRANS(fn_len);
10721
10722                 if (check_col(pinfo->cinfo, COL_INFO)) {
10723                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10724                             format_text(fn, strlen(fn)));
10725                 }
10726                 break;
10727         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10728                 /* XXX unknown structure*/
10729                 break;
10730         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10731                 /* referral level */
10732                 CHECK_BYTE_COUNT_TRANS(2);
10733                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10734                 COUNT_BYTES_TRANS(2);
10735
10736                 /* file name */
10737                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10738                 CHECK_STRING_TRANS(fn);
10739                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10740                         fn);
10741                 COUNT_BYTES_TRANS(fn_len);
10742
10743                 if (check_col(pinfo->cinfo, COL_INFO)) {
10744                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10745                             format_text(fn, strlen(fn)));
10746                 }
10747
10748                 break;
10749         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10750                 /* file name */
10751                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10752                 CHECK_STRING_TRANS(fn);
10753                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10754                         fn);
10755                 COUNT_BYTES_TRANS(fn_len);
10756
10757                 if (check_col(pinfo->cinfo, COL_INFO)) {
10758                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10759                             format_text(fn, strlen(fn)));
10760                 }
10761
10762                 break;
10763         }
10764
10765         /* ooops there were data we didnt know how to process */
10766         if(bc != 0){
10767                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10768                 offset += bc;
10769         }
10770
10771         return offset;
10772 }
10773
10774 /*
10775  * XXX - just use "dissect_connect_flags()" here?
10776  */
10777 static guint16
10778 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10779 {
10780         guint16 mask;
10781         proto_item *item = NULL;
10782         proto_tree *tree = NULL;
10783
10784         mask = tvb_get_letohs(tvb, offset);
10785
10786         if(parent_tree){
10787                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10788                         "Flags: 0x%04x", mask);
10789                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10790         }
10791
10792         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10793                 tvb, offset, 2, mask);
10794         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10795                 tvb, offset, 2, mask);
10796
10797         return mask;
10798 }
10799
10800
10801 static int
10802 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10803 {
10804         guint16 mask;
10805         proto_item *item = NULL;
10806         proto_tree *tree = NULL;
10807
10808         mask = tvb_get_letohs(tvb, offset);
10809
10810         if(parent_tree){
10811                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10812                         "Flags: 0x%04x", mask);
10813                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10814         }
10815
10816         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10817                 tvb, offset, 2, mask);
10818         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10819                 tvb, offset, 2, mask);
10820
10821         offset += 2;
10822         return offset;
10823 }
10824
10825 static int
10826 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10827 {
10828         guint16 mask;
10829         proto_item *item = NULL;
10830         proto_tree *tree = NULL;
10831
10832         mask = tvb_get_letohs(tvb, offset);
10833
10834         if(parent_tree){
10835                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10836                         "Flags: 0x%04x", mask);
10837                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10838         }
10839
10840         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10841                 tvb, offset, 2, mask);
10842
10843         offset += 2;
10844
10845         return offset;
10846 }
10847
10848
10849 /* dfs inconsistency data  (4.4.2)
10850 */
10851 static int
10852 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10853     proto_tree *tree, int offset, guint16 *bcp)
10854 {
10855         smb_info_t *si = pinfo->private_data;
10856         int fn_len;
10857         const char *fn;
10858
10859         DISSECTOR_ASSERT(si);
10860
10861         /*XXX shouldn this data hold version and size? unclear from doc*/
10862         /* referral version */
10863         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10864         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10865         COUNT_BYTES_TRANS_SUBR(2);
10866
10867         /* referral size */
10868         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10869         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10870         COUNT_BYTES_TRANS_SUBR(2);
10871
10872         /* referral server type */
10873         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10874         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10875         COUNT_BYTES_TRANS_SUBR(2);
10876
10877         /* referral flags */
10878         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10879         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10880         *bcp -= 2;
10881
10882         /* node name */
10883         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10884         CHECK_STRING_TRANS_SUBR(fn);
10885         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10886                 fn);
10887         COUNT_BYTES_TRANS_SUBR(fn_len);
10888
10889         return offset;
10890 }
10891
10892 /* get dfs referral data  (4.4.1)
10893 */
10894 static int
10895 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10896     proto_tree *tree, int offset, guint16 *bcp)
10897 {
10898         smb_info_t *si = pinfo->private_data;
10899         guint16 numref;
10900         guint16 refsize;
10901         guint16 pathoffset;
10902         guint16 altpathoffset;
10903         guint16 nodeoffset;
10904         int fn_len;
10905         int stroffset;
10906         int offsetoffset;
10907         guint16 save_bc;
10908         const char *fn;
10909         int unklen;
10910         int ucstring_end;
10911         int ucstring_len;
10912
10913         DISSECTOR_ASSERT(si);
10914
10915         /* path consumed */
10916         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10917         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10918         COUNT_BYTES_TRANS_SUBR(2);
10919
10920         /* num referrals */
10921         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10922         numref = tvb_get_letohs(tvb, offset);
10923         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10924         COUNT_BYTES_TRANS_SUBR(2);
10925
10926         /* get dfs flags */
10927         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10928         offset = dissect_get_dfs_flags(tvb, tree, offset);
10929         *bcp -= 2;
10930
10931         /* XXX - in at least one capture there appears to be 2 bytes
10932            of stuff after the Dfs flags, perhaps so that the header
10933            in front of the referral list is a multiple of 4 bytes long. */
10934         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10935         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10936         COUNT_BYTES_TRANS_SUBR(2);
10937
10938         /* if there are any referrals */
10939         if(numref){
10940                 proto_item *ref_item = NULL;
10941                 proto_tree *ref_tree = NULL;
10942                 int old_offset=offset;
10943
10944                 if(tree){
10945                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
10946                         ref_item = proto_tree_add_text(tree,
10947                                 tvb, offset, *bcp, "Referrals");
10948                         ref_tree = proto_item_add_subtree(ref_item,
10949                                 ett_smb_dfs_referrals);
10950                 }
10951                 ucstring_end = -1;
10952
10953                 while(numref--){
10954                         proto_item *ri = NULL;
10955                         proto_tree *rt = NULL;
10956                         int old_offset=offset;
10957                         guint16 version;
10958
10959                         if(tree){
10960                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
10961                                 ri = proto_tree_add_text(ref_tree,
10962                                         tvb, offset, *bcp, "Referral");
10963                                 rt = proto_item_add_subtree(ri,
10964                                         ett_smb_dfs_referral);
10965                         }
10966
10967                         /* referral version */
10968                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10969                         version = tvb_get_letohs(tvb, offset);
10970                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10971                                 tvb, offset, 2, version);
10972                         COUNT_BYTES_TRANS_SUBR(2);
10973
10974                         /* referral size */
10975                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10976                         refsize = tvb_get_letohs(tvb, offset);
10977                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10978                         COUNT_BYTES_TRANS_SUBR(2);
10979
10980                         /* referral server type */
10981                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10982                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10983                         COUNT_BYTES_TRANS_SUBR(2);
10984
10985                         /* referral flags */
10986                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10987                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10988                         *bcp -= 2;
10989
10990                         switch(version){
10991
10992                         case 1:
10993                                 /* node name */
10994                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10995                                 CHECK_STRING_TRANS_SUBR(fn);
10996                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10997                                         fn);
10998                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10999                                 break;
11000
11001                         case 2:
11002                         case 3: /* XXX - like version 2, but not identical;
11003                                    seen in a capture, but the format isn't
11004                                    documented */
11005                                 /* proximity */
11006                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11007                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
11008                                 COUNT_BYTES_TRANS_SUBR(2);
11009
11010                                 /* ttl */
11011                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11012                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
11013                                 COUNT_BYTES_TRANS_SUBR(2);
11014
11015                                 /* path offset */
11016                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11017                                 pathoffset = tvb_get_letohs(tvb, offset);
11018                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11019                                 COUNT_BYTES_TRANS_SUBR(2);
11020
11021                                 /* alt path offset */
11022                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11023                                 altpathoffset = tvb_get_letohs(tvb, offset);
11024                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11025                                 COUNT_BYTES_TRANS_SUBR(2);
11026
11027                                 /* node offset */
11028                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11029                                 nodeoffset = tvb_get_letohs(tvb, offset);
11030                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11031                                 COUNT_BYTES_TRANS_SUBR(2);
11032
11033                                 /* path */
11034                                 if (pathoffset != 0) {
11035                                         stroffset = old_offset + pathoffset;
11036                                         offsetoffset = stroffset - offset;
11037                                         if (offsetoffset > 0 &&
11038                                             *bcp > offsetoffset) {
11039                                                 save_bc = *bcp;
11040                                                 *bcp -= offsetoffset;
11041                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11042                                                 CHECK_STRING_TRANS_SUBR(fn);
11043                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
11044                                                         fn);
11045                                                 stroffset += fn_len;
11046                                                 if (ucstring_end < stroffset)
11047                                                         ucstring_end = stroffset;
11048                                                 *bcp = save_bc;
11049                                         }
11050                                 }
11051
11052                                 /* alt path */
11053                                 if (altpathoffset != 0) {
11054                                         stroffset = old_offset + altpathoffset;
11055                                         offsetoffset = stroffset - offset;
11056                                         if (offsetoffset > 0 &&
11057                                             *bcp > offsetoffset) {
11058                                                 save_bc = *bcp;
11059                                                 *bcp -= offsetoffset;
11060                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11061                                                 CHECK_STRING_TRANS_SUBR(fn);
11062                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
11063                                                         fn);
11064                                                 stroffset += fn_len;
11065                                                 if (ucstring_end < stroffset)
11066                                                         ucstring_end = stroffset;
11067                                                 *bcp = save_bc;
11068                                         }
11069                                 }
11070
11071                                 /* node */
11072                                 if (nodeoffset != 0) {
11073                                         stroffset = old_offset + nodeoffset;
11074                                         offsetoffset = stroffset - offset;
11075                                         if (offsetoffset > 0 &&
11076                                             *bcp > offsetoffset) {
11077                                                 save_bc = *bcp;
11078                                                 *bcp -= offsetoffset;
11079                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11080                                                 CHECK_STRING_TRANS_SUBR(fn);
11081                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
11082                                                         fn);
11083                                                 stroffset += fn_len;
11084                                                 if (ucstring_end < stroffset)
11085                                                         ucstring_end = stroffset;
11086                                                 *bcp = save_bc;
11087                                         }
11088                                 }
11089                                 break;
11090                         }
11091
11092                         /*
11093                          * Show anything beyond the length of the referral
11094                          * as unknown data.
11095                          */
11096                         unklen = (old_offset + refsize) - offset;
11097                         if (unklen < 0) {
11098                                 /*
11099                                  * XXX - the length is bogus.
11100                                  */
11101                                 unklen = 0;
11102                         }
11103                         if (unklen != 0) {
11104                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11105                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11106                                     offset, unklen, TRUE);
11107                                 COUNT_BYTES_TRANS_SUBR(unklen);
11108                         }
11109
11110                         proto_item_set_len(ri, offset-old_offset);
11111                 }
11112
11113                 /*
11114                  * Treat the offset past the end of the last Unicode
11115                  * string after the referrals (if any) as the last
11116                  * offset.
11117                  */
11118                 if (ucstring_end > offset) {
11119                         ucstring_len = ucstring_end - offset;
11120                         if (*bcp < ucstring_len)
11121                                 ucstring_len = *bcp;
11122                         offset += ucstring_len;
11123                         *bcp -= ucstring_len;
11124                 }
11125                 proto_item_set_len(ref_item, offset-old_offset);
11126         }
11127
11128         return offset;
11129 }
11130
11131 /* This dissects the standard four 8-byte Windows timestamps ...
11132  */
11133 static int
11134 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11135     packet_info *pinfo _U_, proto_tree *tree,
11136     int offset, guint16 *bcp, gboolean *trunc)
11137 {
11138         /* create time */
11139         CHECK_BYTE_COUNT_SUBR(8);
11140         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11141         *bcp -= 8;
11142
11143         /* access time */
11144         CHECK_BYTE_COUNT_SUBR(8);
11145         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11146         *bcp -= 8;
11147
11148         /* last write time */
11149         CHECK_BYTE_COUNT_SUBR(8);
11150         offset = dissect_nt_64bit_time(tvb, tree, offset,
11151                 hf_smb_last_write_time);
11152         *bcp -= 8;
11153
11154         /* last change time */
11155         CHECK_BYTE_COUNT_SUBR(8);
11156         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11157         *bcp -= 8;
11158
11159         *trunc = FALSE;
11160         return offset;
11161 }
11162
11163 /* this dissects the SMB_INFO_STANDARD
11164    as described in 4.2.16.1
11165 */
11166 static int
11167 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11168     int offset, guint16 *bcp, gboolean *trunc)
11169 {
11170         /* create time */
11171         CHECK_BYTE_COUNT_SUBR(4);
11172         offset = dissect_smb_datetime(tvb, tree, offset,
11173                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11174                 FALSE);
11175         *bcp -= 4;
11176
11177         /* access time */
11178         CHECK_BYTE_COUNT_SUBR(4);
11179         offset = dissect_smb_datetime(tvb, tree, offset,
11180                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11181                 FALSE);
11182         *bcp -= 4;
11183
11184         /* last write time */
11185         CHECK_BYTE_COUNT_SUBR(4);
11186         offset = dissect_smb_datetime(tvb, tree, offset,
11187                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11188                 FALSE);
11189         *bcp -= 4;
11190
11191         /* data size */
11192         CHECK_BYTE_COUNT_SUBR(4);
11193         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11194         COUNT_BYTES_SUBR(4);
11195
11196         /* allocation size */
11197         CHECK_BYTE_COUNT_SUBR(4);
11198         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11199         COUNT_BYTES_SUBR(4);
11200
11201         /* File Attributes */
11202         CHECK_BYTE_COUNT_SUBR(2);
11203         offset = dissect_file_attributes(tvb, tree, offset, 2);
11204         *bcp -= 2;
11205
11206         /* ea length */
11207         CHECK_BYTE_COUNT_SUBR(4);
11208         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11209         COUNT_BYTES_SUBR(4);
11210
11211         *trunc = FALSE;
11212         return offset;
11213 }
11214
11215 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11216    as described in 4.2.16.2
11217 */
11218 static int
11219 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11220     int offset, guint16 *bcp, gboolean *trunc)
11221 {
11222         guint8 name_len;
11223         guint16 data_len;
11224         /* EA size */
11225
11226         CHECK_BYTE_COUNT_SUBR(4);
11227         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11228         COUNT_BYTES_SUBR(4);
11229
11230         while (*bcp > 0) {
11231                 proto_item *item;
11232                 proto_tree *subtree;
11233                 int start_offset = offset;
11234                 guint8 *name;
11235
11236                 item = proto_tree_add_text(
11237                         tree, tvb, offset, 0, "Extended Attribute");
11238                 subtree = proto_item_add_subtree(item, ett_smb_ea);
11239
11240                 /* EA flags */
11241                 
11242                 CHECK_BYTE_COUNT_SUBR(1);
11243                 proto_tree_add_item(
11244                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
11245                 COUNT_BYTES_SUBR(1);
11246
11247                 /* EA name length */
11248                 
11249                 name_len = tvb_get_guint8(tvb, offset);
11250
11251                 CHECK_BYTE_COUNT_SUBR(1);
11252                 proto_tree_add_item(
11253                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
11254                 COUNT_BYTES_SUBR(1);
11255
11256                 /* EA data length */
11257
11258                 data_len = tvb_get_letohs(tvb, offset);
11259                 
11260                 CHECK_BYTE_COUNT_SUBR(2);
11261                 proto_tree_add_item(
11262                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
11263                 COUNT_BYTES_SUBR(2);
11264
11265                 /* EA name */
11266
11267                 name = tvb_get_ephemeral_string(tvb, offset, name_len);
11268                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
11269
11270                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
11271                 proto_tree_add_item(
11272                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
11273                         TRUE);
11274                 COUNT_BYTES_SUBR(name_len + 1);
11275
11276                 /* EA data */
11277                 
11278                 CHECK_BYTE_COUNT_SUBR(data_len);
11279                 proto_tree_add_item(
11280                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
11281                 COUNT_BYTES_SUBR(data_len);
11282
11283                 proto_item_set_len(item, offset - start_offset);
11284         }
11285
11286         *trunc = FALSE;
11287         return offset;
11288 }
11289
11290 /* this dissects the SMB_INFO_IS_NAME_VALID
11291    as described in 4.2.16.3
11292 */
11293 static int
11294 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11295     int offset, guint16 *bcp, gboolean *trunc)
11296 {
11297         smb_info_t *si = pinfo->private_data;
11298         int fn_len;
11299         const char *fn;
11300
11301         DISSECTOR_ASSERT(si);
11302
11303         /* file name */
11304         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11305         CHECK_STRING_SUBR(fn);
11306         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11307                 fn);
11308         COUNT_BYTES_SUBR(fn_len);
11309
11310         *trunc = FALSE;
11311         return offset;
11312 }
11313
11314 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11315    as described in 4.2.16.4
11316 */
11317 static int
11318 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11319     int offset, guint16 *bcp, gboolean *trunc)
11320 {
11321
11322         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11323         if (*trunc) {
11324           return offset;
11325         }
11326
11327         /* File Attributes */
11328         CHECK_BYTE_COUNT_SUBR(4);
11329         offset = dissect_file_attributes(tvb, tree, offset, 4);
11330         *bcp -= 4;
11331
11332         *trunc = FALSE;
11333         return offset;
11334 }
11335
11336 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11337    as described in 4.2.16.5
11338 */
11339 int
11340 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11341     int offset, guint16 *bcp, gboolean *trunc)
11342 {
11343         /* allocation size */
11344         CHECK_BYTE_COUNT_SUBR(8);
11345         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11346         COUNT_BYTES_SUBR(8);
11347
11348         /* end of file */
11349         CHECK_BYTE_COUNT_SUBR(8);
11350         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11351         COUNT_BYTES_SUBR(8);
11352
11353         /* number of links */
11354         CHECK_BYTE_COUNT_SUBR(4);
11355         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11356         COUNT_BYTES_SUBR(4);
11357
11358         /* delete pending */
11359         CHECK_BYTE_COUNT_SUBR(1);
11360         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11361         COUNT_BYTES_SUBR(1);
11362
11363         /* is directory */
11364         CHECK_BYTE_COUNT_SUBR(1);
11365         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11366         COUNT_BYTES_SUBR(1);
11367
11368         *trunc = FALSE;
11369         return offset;
11370 }
11371
11372 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
11373 */
11374 int
11375 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11376     int offset, guint16 *bcp, gboolean *trunc)
11377 {
11378         /* file id */
11379         CHECK_BYTE_COUNT_SUBR(8);
11380         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11381         COUNT_BYTES_SUBR(8);
11382
11383         *trunc = FALSE;
11384         return offset;
11385 }
11386
11387 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
11388 */
11389 int
11390 dissect_qfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11391     int offset, guint16 *bcp, gboolean *trunc)
11392 {
11393         /* file id */
11394         CHECK_BYTE_COUNT_SUBR(8);
11395         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, TRUE);
11396         COUNT_BYTES_SUBR(8);
11397
11398         *trunc = FALSE;
11399         return offset;
11400 }
11401
11402 /* this dissects the SMB_QUERY_FILE_MODE_INFO
11403 */
11404 int
11405 dissect_qfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11406     int offset, guint16 *bcp, gboolean *trunc)
11407 {
11408         /* mode */
11409         CHECK_BYTE_COUNT_SUBR(4);
11410         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, TRUE);
11411         COUNT_BYTES_SUBR(4);
11412
11413         *trunc = FALSE;
11414         return offset;
11415 }
11416
11417 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
11418 */
11419 int
11420 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11421     int offset, guint16 *bcp, gboolean *trunc)
11422 {
11423         /* alignment */
11424         CHECK_BYTE_COUNT_SUBR(4);
11425         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11426         COUNT_BYTES_SUBR(4);
11427
11428         *trunc = FALSE;
11429         return offset;
11430 }
11431
11432 /* this dissects the SMB_QUERY_FILE_EA_INFO
11433    as described in 4.2.16.6
11434 */
11435 int
11436 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11437     int offset, guint16 *bcp, gboolean *trunc)
11438 {
11439         /* ea length */
11440         CHECK_BYTE_COUNT_SUBR(4);
11441         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11442         COUNT_BYTES_SUBR(4);
11443
11444         *trunc = FALSE;
11445         return offset;
11446 }
11447
11448 /* this dissects the SMB_QUERY_FILE_ALLOCATION_INFO
11449 */
11450 int
11451 dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11452     int offset, guint16 *bcp, gboolean *trunc)
11453 {
11454         /* allocation size */
11455         CHECK_BYTE_COUNT_SUBR(8);
11456         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11457         COUNT_BYTES_SUBR(8);
11458
11459         *trunc = FALSE;
11460         return offset;
11461 }
11462
11463 /* this dissects the SMB_QUERY_FILE_ENDOFFILE_INFO
11464 */
11465 int
11466 dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11467     int offset, guint16 *bcp, gboolean *trunc)
11468 {
11469         /* end of file */
11470         CHECK_BYTE_COUNT_SUBR(8);
11471         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11472         COUNT_BYTES_SUBR(8);
11473
11474         *trunc = FALSE;
11475         return offset;
11476 }
11477
11478 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11479    as described in 4.2.16.7
11480    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11481    as described in 4.2.16.9
11482 */
11483 int
11484 dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11485     int offset, guint16 *bcp, gboolean *trunc)
11486 {
11487         smb_info_t *si = pinfo->private_data;
11488         int fn_len;
11489         const char *fn;
11490
11491         DISSECTOR_ASSERT(si);
11492
11493         /* file name len */
11494         CHECK_BYTE_COUNT_SUBR(4);
11495         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11496         COUNT_BYTES_SUBR(4);
11497
11498         /* file name */
11499         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11500         CHECK_STRING_SUBR(fn);
11501         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11502                 fn);
11503         COUNT_BYTES_SUBR(fn_len);
11504
11505         *trunc = FALSE;
11506         return offset;
11507 }
11508
11509 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11510    but not as described in 4.2.16.8 since CNIA spec is wrong 
11511 */
11512 static int
11513 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11514     int offset, guint16 *bcp, gboolean *trunc)
11515 {
11516         smb_info_t *si;
11517         guint32 fn_len;
11518         const char *fn;
11519
11520         si = (smb_info_t *)pinfo->private_data;
11521
11522         DISSECTOR_ASSERT(si);
11523
11524         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11525         if (*trunc) {
11526           return offset;
11527         }
11528
11529         /* File Attributes */
11530         CHECK_BYTE_COUNT_SUBR(4);
11531         offset = dissect_file_attributes(tvb, tree, offset, 4);
11532         *bcp -= 4;
11533
11534         /* 4 pad bytes */
11535         offset+=4;
11536         *bcp -= 4;
11537
11538         /* allocation size */
11539         CHECK_BYTE_COUNT_SUBR(8);
11540         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11541         COUNT_BYTES_SUBR(8);
11542
11543         /* end of file */
11544         CHECK_BYTE_COUNT_SUBR(8);
11545         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11546         COUNT_BYTES_SUBR(8);
11547
11548         /* number of links */
11549         CHECK_BYTE_COUNT_SUBR(4);
11550         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11551         COUNT_BYTES_SUBR(4);
11552
11553         /* delete pending */
11554         CHECK_BYTE_COUNT_SUBR(1);
11555         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11556         COUNT_BYTES_SUBR(1);
11557
11558         /* is directory */
11559         CHECK_BYTE_COUNT_SUBR(1);
11560         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11561         COUNT_BYTES_SUBR(1);
11562
11563         /* 2 pad bytes */
11564         offset+=2;
11565         *bcp -= 2;
11566
11567         /* ea length */
11568         CHECK_BYTE_COUNT_SUBR(4);
11569         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11570         COUNT_BYTES_SUBR(4);
11571
11572         /* file name len */
11573         CHECK_BYTE_COUNT_SUBR(4);
11574         fn_len = (guint32)tvb_get_letohl(tvb, offset);
11575         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11576         COUNT_BYTES_SUBR(4);
11577
11578
11579         /* file name */
11580         CHECK_BYTE_COUNT_SUBR(fn_len);
11581         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
11582         if (fn != NULL) {
11583                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11584                         fn);
11585                 COUNT_BYTES_SUBR(fn_len);
11586         }
11587
11588
11589         if (*trunc)
11590                 return offset;
11591
11592         return offset;
11593 }
11594
11595 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11596    as described in 4.2.16.10
11597 */
11598 int
11599 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
11600     int offset, guint16 *bcp, gboolean *trunc, int unicode)
11601 {
11602         proto_item *item;
11603         proto_tree *tree;
11604         int old_offset;
11605         guint32 neo;
11606         int fn_len;
11607         const char *fn;
11608         int padcnt;
11609
11610
11611         for (;;) {
11612                 old_offset = offset;
11613
11614                 /* next entry offset */
11615                 CHECK_BYTE_COUNT_SUBR(4);
11616                 if(parent_tree){
11617                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11618                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11619                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11620                 } else {
11621                         item = NULL;
11622                         tree = NULL;
11623                 }
11624
11625                 neo = tvb_get_letohl(tvb, offset);
11626                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11627                 COUNT_BYTES_SUBR(4);
11628
11629                 /* stream name len */
11630                 CHECK_BYTE_COUNT_SUBR(4);
11631                 fn_len = tvb_get_letohl(tvb, offset);
11632                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11633                 COUNT_BYTES_SUBR(4);
11634
11635                 /* stream size */
11636                 CHECK_BYTE_COUNT_SUBR(8);
11637                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11638                 COUNT_BYTES_SUBR(8);
11639
11640                 /* allocation size */
11641                 CHECK_BYTE_COUNT_SUBR(8);
11642                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11643                 COUNT_BYTES_SUBR(8);
11644
11645                 /* stream name */
11646                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
11647                 CHECK_STRING_SUBR(fn);
11648                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11649                         fn);
11650                 COUNT_BYTES_SUBR(fn_len);
11651
11652                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
11653                 proto_item_set_len(item, offset-old_offset);
11654
11655                 if (neo == 0)
11656                         break;  /* no more structures */
11657
11658                 /* skip to next structure */
11659                 padcnt = (old_offset + neo) - offset;
11660                 if (padcnt < 0) {
11661                         /*
11662                          * XXX - this is bogus; flag it?
11663                          */
11664                         padcnt = 0;
11665                 }
11666                 if (padcnt != 0) {
11667                         CHECK_BYTE_COUNT_SUBR(padcnt);
11668                         COUNT_BYTES_SUBR(padcnt);
11669                 }
11670         }
11671
11672         *trunc = FALSE;
11673         return offset;
11674 }
11675
11676 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11677    as described in 4.2.16.11
11678 */
11679 int
11680 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11681     int offset, guint16 *bcp, gboolean *trunc)
11682 {
11683         /* compressed file size */
11684         CHECK_BYTE_COUNT_SUBR(8);
11685         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11686         COUNT_BYTES_SUBR(8);
11687
11688         /* compression format */
11689         CHECK_BYTE_COUNT_SUBR(2);
11690         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11691         COUNT_BYTES_SUBR(2);
11692
11693         /* compression unit shift */
11694         CHECK_BYTE_COUNT_SUBR(1);
11695         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11696         COUNT_BYTES_SUBR(1);
11697
11698         /* compression chunk shift */
11699         CHECK_BYTE_COUNT_SUBR(1);
11700         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11701         COUNT_BYTES_SUBR(1);
11702
11703         /* compression cluster shift */
11704         CHECK_BYTE_COUNT_SUBR(1);
11705         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11706         COUNT_BYTES_SUBR(1);
11707
11708         /* 3 reserved bytes */
11709         CHECK_BYTE_COUNT_SUBR(3);
11710         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11711         COUNT_BYTES_SUBR(3);
11712
11713         *trunc = FALSE;
11714         return offset;
11715 }
11716
11717 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11718
11719 static const value_string unix_file_type_vals[] = {
11720         { 0, "File" },
11721         { 1, "Directory" },
11722         { 2, "Symbolic link" },
11723         { 3, "Character device" },
11724         { 4, "Block device" },
11725         { 5, "FIFO" },
11726         { 6, "Socket" },
11727         { 0, NULL }
11728 };
11729
11730 static int
11731 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11732                   int offset, guint16 *bcp, gboolean *trunc)
11733 {
11734         /* End of file (file size) */
11735         CHECK_BYTE_COUNT_SUBR(8);
11736         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11737         COUNT_BYTES_SUBR(8);
11738
11739         /* Number of bytes */
11740         CHECK_BYTE_COUNT_SUBR(8);
11741         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11742         COUNT_BYTES_SUBR(8);
11743
11744         /* Last status change */
11745         CHECK_BYTE_COUNT_SUBR(8);
11746         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11747         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
11748
11749         /* Last access time */
11750         CHECK_BYTE_COUNT_SUBR(8);
11751         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11752         *bcp -= 8;
11753
11754         /* Last modification time */
11755         CHECK_BYTE_COUNT_SUBR(8);
11756         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11757         *bcp -= 8;
11758
11759         /* File owner uid */
11760         CHECK_BYTE_COUNT_SUBR(8);
11761         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11762         COUNT_BYTES_SUBR(8);
11763
11764         /* File group gid */
11765         CHECK_BYTE_COUNT_SUBR(8);
11766         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11767         COUNT_BYTES_SUBR(8);
11768
11769         /* File type */
11770         CHECK_BYTE_COUNT_SUBR(4);
11771         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11772         COUNT_BYTES_SUBR(4);
11773
11774         /* Major device number */
11775         CHECK_BYTE_COUNT_SUBR(8);
11776         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11777         COUNT_BYTES_SUBR(8);
11778
11779         /* Minor device number */
11780         CHECK_BYTE_COUNT_SUBR(8);
11781         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11782         COUNT_BYTES_SUBR(8);
11783
11784         /* Unique id */
11785         CHECK_BYTE_COUNT_SUBR(8);
11786         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11787         COUNT_BYTES_SUBR(8);
11788
11789         /* Permissions */
11790         CHECK_BYTE_COUNT_SUBR(8);
11791         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11792         COUNT_BYTES_SUBR(8);
11793
11794         /* Nlinks */
11795         CHECK_BYTE_COUNT_SUBR(8);
11796         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11797         COUNT_BYTES_SUBR(8);
11798
11799         /* Sometimes there is one extra byte in the data field which I
11800            guess could be padding, but we are only using 4 or 8 byte
11801            data types so this is a bit confusing. -tpot */
11802
11803         *trunc = FALSE;
11804         return offset;
11805 }
11806
11807 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11808
11809 static int
11810 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11811                   int offset, guint16 *bcp, gboolean *trunc)
11812 {
11813         smb_info_t *si = pinfo->private_data;
11814         const char *fn;
11815         int fn_len;
11816
11817         DISSECTOR_ASSERT(si);
11818
11819         /* Link destination */
11820
11821         fn = get_unicode_or_ascii_string(
11822                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11823
11824         CHECK_STRING_SUBR(fn);
11825         proto_tree_add_string(
11826                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11827         COUNT_BYTES_SUBR(fn_len);
11828
11829         *trunc = FALSE;
11830         return offset;
11831 }
11832
11833 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
11834 */
11835 int
11836 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb, 
11837     packet_info *pinfo, proto_tree *tree,
11838     int offset, guint16 *bcp, gboolean *trunc)
11839 {
11840
11841         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11842         if (*trunc) {
11843           return offset;
11844         }
11845
11846         /* allocation size */
11847         CHECK_BYTE_COUNT_SUBR(8);
11848         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11849         COUNT_BYTES_SUBR(8);
11850
11851         /* end of file */
11852         CHECK_BYTE_COUNT_SUBR(8);
11853         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11854         COUNT_BYTES_SUBR(8);
11855
11856         /* File Attributes */
11857         CHECK_BYTE_COUNT_SUBR(4);
11858         offset = dissect_file_attributes(tvb, tree, offset, 4);
11859         *bcp -= 4;
11860
11861         /* Unknown, possibly count of network accessors ... */
11862         CHECK_BYTE_COUNT_SUBR(4);
11863         proto_tree_add_item(tree, hf_smb_network_unknown, tvb, offset, 4, TRUE);
11864         COUNT_BYTES_SUBR(4);
11865
11866         *trunc = FALSE;
11867         return offset;
11868 }
11869
11870 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
11871 */
11872 int
11873 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb, 
11874     packet_info *pinfo _U_, proto_tree *tree,
11875     int offset, guint16 *bcp, gboolean *trunc)
11876 {
11877         /* attribute */
11878         CHECK_BYTE_COUNT_SUBR(4);
11879         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, TRUE);
11880         COUNT_BYTES_SUBR(4);
11881
11882         /* reparse tag */
11883         CHECK_BYTE_COUNT_SUBR(4);
11884         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, TRUE);
11885         COUNT_BYTES_SUBR(4);
11886
11887         *trunc = FALSE;
11888         return offset;
11889 }
11890
11891 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11892    as described in 4.2.19.2
11893 */
11894 static int
11895 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11896     int offset, guint16 *bcp, gboolean *trunc)
11897 {
11898         /* marked for deletion? */
11899         CHECK_BYTE_COUNT_SUBR(1);
11900         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11901         COUNT_BYTES_SUBR(1);
11902
11903         *trunc = FALSE;
11904         return offset;
11905 }
11906
11907 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11908    as described in 4.2.19.3
11909 */
11910 static int
11911 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11912     int offset, guint16 *bcp, gboolean *trunc)
11913 {
11914         /* file allocation size */
11915         CHECK_BYTE_COUNT_SUBR(8);
11916         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11917         COUNT_BYTES_SUBR(8);
11918
11919         *trunc = FALSE;
11920         return offset;
11921 }
11922
11923 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11924    as described in 4.2.19.4
11925 */
11926 static int
11927 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11928     int offset, guint16 *bcp, gboolean *trunc)
11929 {
11930         /* file end of file offset */
11931         CHECK_BYTE_COUNT_SUBR(8);
11932         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11933         COUNT_BYTES_SUBR(8);
11934
11935         *trunc = FALSE;
11936         return offset;
11937 }
11938
11939 /* Set File Rename Info */
11940
11941 static const true_false_string tfs_smb_replace = {
11942         "Remove target file if it exists",
11943         "Do NOT remove target file if it exists",
11944 };
11945
11946 static int
11947 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11948                     int offset, guint16 *bcp, gboolean *trunc)
11949 {
11950         smb_info_t *si = pinfo->private_data;
11951         const char *fn;
11952         guint32 target_name_len;
11953         int fn_len;
11954
11955         DISSECTOR_ASSERT(si);
11956
11957         /* Replace flag */
11958         CHECK_BYTE_COUNT_SUBR(4);
11959         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
11960         COUNT_BYTES_SUBR(4);
11961
11962         /* Root directory handle */
11963         CHECK_BYTE_COUNT_SUBR(4);
11964         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
11965         COUNT_BYTES_SUBR(4);
11966
11967         /* Target name length */
11968         CHECK_BYTE_COUNT_SUBR(4);
11969         target_name_len = tvb_get_letohl(tvb, offset);
11970         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
11971         COUNT_BYTES_SUBR(4);
11972
11973         /* Target name */
11974         fn_len = target_name_len;
11975         fn = get_unicode_or_ascii_string(
11976                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11977
11978         CHECK_STRING_SUBR(fn);
11979         proto_tree_add_string(
11980                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
11981         COUNT_BYTES_SUBR(fn_len);
11982
11983         *trunc = FALSE;
11984         return offset;
11985 }
11986
11987 static int
11988 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11989                     int offset, guint16 *bcp, gboolean *trunc)
11990 {
11991         smb_info_t *si = pinfo->private_data;
11992 /*      const char *fn;*/
11993 /*      guint32 target_name_len;*/
11994 /*      int fn_len;*/
11995
11996         DISSECTOR_ASSERT(si);
11997
11998         /* Disposition flags */
11999         CHECK_BYTE_COUNT_SUBR(1);
12000         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, TRUE);
12001         COUNT_BYTES_SUBR(1);
12002
12003         *trunc = FALSE;
12004         return offset;
12005 }
12006
12007 int
12008 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12009                     int offset, guint16 *bcp, gboolean *trunc)
12010 {
12011         smb_info_t *si = pinfo->private_data;
12012
12013         DISSECTOR_ASSERT(si);
12014
12015         /* pipe info flag */
12016         CHECK_BYTE_COUNT_SUBR(1);
12017         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, TRUE);
12018         COUNT_BYTES_SUBR(1);
12019
12020         *trunc = FALSE;
12021         return offset;
12022 }
12023
12024 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
12025   TRANS2_QUERY_FILE_INFORMATION*/
12026 static int
12027 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12028     int offset, guint16 *bcp)
12029 {
12030         smb_info_t *si;
12031         gboolean trunc;
12032
12033         if(!*bcp){
12034                 return offset;
12035         }
12036
12037         si = (smb_info_t *)pinfo->private_data;
12038         DISSECTOR_ASSERT(si);
12039
12040         switch(si->info_level){
12041         case 1:         /*Info Standard*/
12042                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12043                     &trunc);
12044                 break;
12045                 
12046         case 2:         /*Info Query EA Size*/
12047                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12048                     &trunc);
12049                 break;
12050         case 3:         /*Info Query EAs From List*/
12051         case 4:         /*Info Query All EAs*/
12052                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12053                     &trunc);
12054                 break;
12055         case 6:         /*Info Is Name Valid*/
12056                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
12057                     &trunc);
12058                 break;
12059         case 0x0101:    /*Query File Basic Info*/
12060         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12061                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12062                     &trunc);
12063                 break;
12064         case 0x0102:    /*Query File Standard Info*/
12065         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
12066                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
12067                     &trunc);
12068                 break;
12069         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
12070                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
12071                     &trunc);
12072                 break;
12073         case 0x0103:    /*Query File EA Info*/
12074         case 1007:      /* SMB_FILE_EA_INFORMATION */
12075                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
12076                     &trunc);
12077                 break;
12078         case 0x0104:    /*Query File Name Info*/
12079         case 1009:      /* SMB_FILE_NAME_INFORMATION */
12080                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12081                     &trunc);
12082                 break;
12083         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
12084                 offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
12085                     &trunc);
12086                 break;
12087         case 1016:      /* SMB_FILE_MODE_INFORMATION */
12088                 offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
12089                     &trunc);
12090                 break;
12091         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
12092                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
12093                     &trunc);
12094                 break;
12095         case 0x0107:    /*Query File All Info*/
12096         case 1018:      /* SMB_FILE_ALL_INFORMATION */
12097                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
12098                     &trunc);
12099                 break;
12100         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
12101                 offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
12102                     &trunc);
12103                 break;
12104         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
12105                 offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
12106                     &trunc);
12107                 break;
12108         case 0x0108:    /*Query File Alt File Info*/
12109         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
12110                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12111                     &trunc);
12112                 break;
12113         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
12114                 si->unicode = TRUE;
12115         case 0x0109:    /*Query File Stream Info*/
12116                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
12117                     &trunc, si->unicode);
12118                 break;
12119         case 0x010b:    /*Query File Compression Info*/
12120         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
12121                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
12122                     &trunc);
12123                 break;
12124         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
12125                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12126                 break;
12127         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
12128                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12129                 break;
12130         case 0x0200:    /* Query File Unix Basic*/
12131                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
12132                                            &trunc);
12133                 break;
12134         case 0x0201:    /* Query File Unix Link*/
12135                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
12136                                            &trunc);
12137                 break;
12138         case 0x0202:    /* Query File Unix HardLink*/
12139                 /* XXX add this from the SNIA doc */
12140                 break;
12141         }
12142
12143         return offset;
12144 }
12145
12146 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
12147   TRANS2_SET_FILE_INFORMATION*/
12148 static int
12149 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12150     int offset, guint16 *bcp)
12151 {
12152         smb_info_t *si;
12153         gboolean trunc;
12154
12155         if(!*bcp){
12156                 return offset;
12157         }
12158
12159         si = (smb_info_t *)pinfo->private_data;
12160         DISSECTOR_ASSERT(si);
12161
12162         switch(si->info_level){
12163         case 1:         /*Info Standard*/
12164                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12165                     &trunc);
12166                 break;
12167         case 2:         /*Info Query EA Size*/
12168                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12169                     &trunc);
12170                 break;
12171         case 4:         /*Info Query All EAs*/
12172                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12173                     &trunc);
12174                 break;
12175         case 0x0101:    /*Set File Basic Info*/
12176         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12177                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12178                     &trunc);
12179                 break;
12180         case 0x0102:    /*Set File Disposition Info*/
12181                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
12182                     &trunc);
12183                 break;
12184         case 0x0103:    /*Set File Allocation Info*/
12185                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
12186                     &trunc);
12187                 break;
12188         case 0x0104:    /*Set End Of File Info*/
12189                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
12190                     &trunc);
12191                 break;
12192         case 0x0200:    /*Set File Unix Basic.  Same as query. */
12193                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12194                     &trunc);
12195                 break;
12196         case 0x0201:    /*Set File Unix Link.  Same as query. */
12197                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12198                     &trunc);
12199                 break;
12200         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
12201                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12202                     &trunc);
12203                 break;
12204         case 1010:      /* Set File Rename */
12205                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
12206                     &trunc);
12207                 break;
12208         case 1013: /* Set Disposition Information */
12209                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
12210                     &trunc);
12211                 break;
12212         case 1023: /* Set Pipe Info */
12213                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
12214                     &trunc);
12215                 break;
12216         case 1014:
12217         case 1016:
12218         case 1019:
12219         case 1020:
12220         case 1025:
12221         case 1029:
12222         case 1032:
12223         case 1039:
12224         case 1040:
12225                 /* XXX: TODO, extra levels discovered by tridge */
12226                 break;
12227         }
12228
12229         return offset;
12230 }
12231
12232
12233 static const true_false_string tfs_quota_flags_deny_disk = {
12234         "DENY DISK SPACE for users exceeding quota limit",
12235         "Do NOT deny disk space for users exceeding quota limit"
12236 };
12237 static const true_false_string tfs_quota_flags_log_limit = {
12238         "LOG EVENT when a user exceeds their QUOTA LIMIT",
12239         "Do NOT log event when a user exceeds their quota limit"
12240 };
12241 static const true_false_string tfs_quota_flags_log_warning = {
12242         "LOG EVENT when a user exceeds their WARNING LEVEL",
12243         "Do NOT log event when a user exceeds their warning level"
12244 };
12245 static const true_false_string tfs_quota_flags_enabled = {
12246         "Quotas are ENABLED of this fs",
12247         "Quotas are NOT enabled on this fs"
12248 };
12249 static void
12250 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12251 {
12252         guint8 mask;
12253         proto_item *item = NULL;
12254         proto_tree *tree = NULL;
12255
12256         mask = tvb_get_guint8(tvb, offset);
12257
12258         if(parent_tree){
12259                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
12260                         "Quota Flags: 0x%02x %s", mask,
12261                         mask?"Enabled":"Disabled");
12262                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
12263         }
12264
12265         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
12266                 tvb, offset, 1, mask);
12267         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
12268                 tvb, offset, 1, mask);
12269         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
12270                 tvb, offset, 1, mask);
12271
12272         if(mask && (!(mask&0x01))){
12273                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
12274                         tvb, offset, 1, 0x01);
12275         } else {
12276                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12277                         tvb, offset, 1, mask);
12278         }
12279
12280 }
12281
12282 int
12283 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
12284 {
12285         /* first 24 bytes are unknown */
12286         CHECK_BYTE_COUNT_TRANS_SUBR(24);
12287         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12288                     offset, 24, TRUE);
12289         COUNT_BYTES_TRANS_SUBR(24);
12290
12291         /* number of bytes for quota warning */
12292         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12293         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
12294         COUNT_BYTES_TRANS_SUBR(8);
12295
12296         /* number of bytes for quota limit */
12297         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12298         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
12299         COUNT_BYTES_TRANS_SUBR(8);
12300
12301         /* one byte of quota flags */
12302         CHECK_BYTE_COUNT_TRANS_SUBR(1);
12303         dissect_quota_flags(tvb, tree, offset);
12304         COUNT_BYTES_TRANS_SUBR(1);
12305
12306         /* these 7 bytes are unknown */
12307         CHECK_BYTE_COUNT_TRANS_SUBR(7);
12308         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12309                     offset, 7, TRUE);
12310         COUNT_BYTES_TRANS_SUBR(7);
12311
12312         return offset;
12313 }
12314
12315 static int
12316 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
12317     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
12318 {
12319         proto_item *item = NULL;
12320         proto_tree *tree = NULL;
12321         smb_info_t *si;
12322
12323         si = (smb_info_t *)pinfo->private_data;
12324         DISSECTOR_ASSERT(si);
12325
12326         if(parent_tree){
12327                 tvb_ensure_bytes_exist(tvb, offset, dc);
12328                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12329                                 "%s Data",
12330                                 val_to_str(subcmd, trans2_cmd_vals,
12331                                                 "Unknown (0x%02x)"));
12332                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12333         }
12334
12335         switch(subcmd){
12336         case 0x00:      /*TRANS2_OPEN2*/
12337                 /* XXX dont know how to decode FEAList */
12338                 break;
12339         case 0x01:      /*TRANS2_FIND_FIRST2*/
12340                 /* XXX dont know how to decode FEAList */
12341                 break;
12342         case 0x02:      /*TRANS2_FIND_NEXT2*/
12343                 /* XXX dont know how to decode FEAList */
12344                 break;
12345         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12346                 /* no data field in this request */
12347                 break;
12348         case 0x04:      /* TRANS2_SET_QUOTA */
12349                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
12350                 break;
12351         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12352                 /* no data field in this request */
12353                 /*
12354                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12355                  * Extensions Version 3.0, Document Version 1.11,
12356                  * July 19, 1990" says there may be "Additional
12357                  * FileInfoLevel dependent information" here.
12358                  *
12359                  * Was that just a cut-and-pasteo?
12360                  * TRANS2_SET_PATH_INFORMATION *does* have that information
12361                  * here.
12362                  */
12363                 break;
12364         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12365                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12366                 break;
12367         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12368                 /* no data field in this request */
12369                 /*
12370                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12371                  * Extensions Version 3.0, Document Version 1.11,
12372                  * July 19, 1990" says there may be "Additional
12373                  * FileInfoLevel dependent information" here.
12374                  *
12375                  * Was that just a cut-and-pasteo?
12376                  * TRANS2_SET_FILE_INFORMATION *does* have that information
12377                  * here.
12378                  */
12379                 break;
12380         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12381                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12382                 break;
12383         case 0x09:      /*TRANS2_FSCTL*/
12384                 /*XXX dont know how to decode this yet */
12385
12386                 /*
12387                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12388                  * Extensions Version 3.0, Document Version 1.11,
12389                  * July 19, 1990" says this this contains a
12390                  * "File system specific data block".  (That means we
12391                  * may not be able to dissect it in any case.)
12392                  */
12393                 break;
12394         case 0x0a:      /*TRANS2_IOCTL2*/
12395                 /*XXX dont know how to decode this yet */
12396
12397                 /*
12398                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12399                  * Extensions Version 3.0, Document Version 1.11,
12400                  * July 19, 1990" says this this contains a
12401                  * "Device/function specific data block".  (That
12402                  * means we may not be able to dissect it in any case.)
12403                  */
12404                 break;
12405         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12406                 /*XXX dont know how to decode this yet */
12407
12408                 /*
12409                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12410                  * Extensions Version 3.0, Document Version 1.11,
12411                  * July 19, 1990" says this this contains "additional
12412                  * level dependent match data".
12413                  */
12414                 break;
12415         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12416                 /*XXX dont know how to decode this yet */
12417
12418                 /*
12419                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12420                  * Extensions Version 3.0, Document Version 1.11,
12421                  * July 19, 1990" says this this contains "additional
12422                  * level dependent monitor information".
12423                  */
12424                 break;
12425         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12426                 /* XXX optional FEAList, unknown what FEAList looks like*/
12427                 break;
12428         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12429                 /*XXX dont know how to decode this yet */
12430                 break;
12431         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12432                 /* no data field in this request */
12433                 break;
12434         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12435                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
12436                 break;
12437         }
12438
12439         /* ooops there were data we didnt know how to process */
12440         if(dc != 0){
12441                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12442                 offset += dc;
12443         }
12444
12445         return offset;
12446 }
12447
12448
12449 static void
12450 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
12451     proto_tree *tree)
12452 {
12453         int i;
12454         int offset;
12455         guint length;
12456
12457         /*
12458          * Show the setup words.
12459          */
12460         if (s_tvb != NULL) {
12461                 length = tvb_reported_length(s_tvb);
12462                 for (i = 0, offset = 0; length >= 2;
12463                     i++, offset += 2, length -= 2) {
12464                         /*
12465                          * XXX - add a setup word filterable field?
12466                          */
12467                         proto_tree_add_text(tree, s_tvb, offset, 2,
12468                             "Setup Word %d: 0x%04x", i,
12469                             tvb_get_letohs(s_tvb, offset));
12470                 }
12471         }
12472
12473         /*
12474          * Show the parameters, if any.
12475          */
12476         if (p_tvb != NULL) {
12477                 length = tvb_reported_length(p_tvb);
12478                 if (length != 0) {
12479                         proto_tree_add_text(tree, p_tvb, 0, length,
12480                             "Parameters: %s",
12481                             tvb_bytes_to_str(p_tvb, 0, length));
12482                 }
12483         }
12484
12485         /*
12486          * Show the data, if any.
12487          */
12488         if (d_tvb != NULL) {
12489                 length = tvb_reported_length(d_tvb);
12490                 if (length != 0) {
12491                         proto_tree_add_text(tree, d_tvb, 0, length,
12492                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
12493                 }
12494         }
12495 }
12496
12497 /* This routine handles the following 4 calls
12498    Transaction  0x25
12499    Transaction Secondary 0x26
12500    Transaction2 0x32
12501    Transaction2 Secondary 0x33
12502 */
12503 static int
12504 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12505 {
12506         guint8 wc, sc=0;
12507         int so=offset;
12508         int sl=0;
12509         int spo=offset;
12510         int spc=0;
12511         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
12512         int subcmd = -1;
12513         guint32 to;
12514         int an_len;
12515         const char *an = NULL;
12516         smb_info_t *si;
12517         smb_transact2_info_t *t2i;
12518         smb_transact_info_t *tri;
12519         guint16 bc;
12520         int padcnt;
12521         gboolean dissected_trans;
12522
12523         si = (smb_info_t *)pinfo->private_data;
12524         DISSECTOR_ASSERT(si);
12525
12526         WORD_COUNT;
12527
12528         if(wc==8){
12529                 /*secondary client request*/
12530
12531                 /* total param count, only a 16bit integer here*/
12532                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12533                 offset += 2;
12534
12535                 /* total data count , only 16bit integer here*/
12536                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12537                 offset += 2;
12538
12539                 /* param count */
12540                 pc = tvb_get_letohs(tvb, offset);
12541                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12542                 offset += 2;
12543
12544                 /* param offset */
12545                 po = tvb_get_letohs(tvb, offset);
12546                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12547                 offset += 2;
12548
12549                 /* param disp */
12550                 pd = tvb_get_letohs(tvb, offset);
12551                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12552                 offset += 2;
12553
12554                 /* data count */
12555                 dc = tvb_get_letohs(tvb, offset);
12556                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12557                 offset += 2;
12558
12559                 /* data offset */
12560                 od = tvb_get_letohs(tvb, offset);
12561                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12562                 offset += 2;
12563
12564                 /* data disp */
12565                 dd = tvb_get_letohs(tvb, offset);
12566                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12567                 offset += 2;
12568
12569                 if(si->cmd==SMB_COM_TRANSACTION2){
12570                         guint16 fid;
12571
12572                         /* fid */
12573                         fid = tvb_get_letohs(tvb, offset);
12574                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
12575
12576                         offset += 2;
12577                 }
12578
12579                 /* There are no setup words. */
12580                 so = offset;
12581                 sc = 0;
12582                 sl = 0;
12583         } else {
12584                 /* it is not a secondary request */
12585
12586                 /* total param count , only a 16 bit integer here*/
12587                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12588                 offset += 2;
12589
12590                 /* total data count , only 16bit integer here*/
12591                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12592                 offset += 2;
12593
12594                 /* max param count , only 16bit integer here*/
12595                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12596                 offset += 2;
12597
12598                 /* max data count, only 16bit integer here*/
12599                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12600                 offset += 2;
12601
12602                 /* max setup count, only 16bit integer here*/
12603                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12604                 offset += 1;
12605
12606                 /* reserved byte */
12607                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12608                 offset += 1;
12609
12610                 /* transaction flags */
12611                 tf = dissect_transaction_flags(tvb, tree, offset);
12612                 offset += 2;
12613
12614                 /* timeout */
12615                 to = tvb_get_letohl(tvb, offset);
12616                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
12617                 offset += 4;
12618
12619                 /* 2 reserved bytes */
12620                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12621                 offset += 2;
12622
12623                 /* param count */
12624                 pc = tvb_get_letohs(tvb, offset);
12625                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12626                 offset += 2;
12627
12628                 /* param offset */
12629                 po = tvb_get_letohs(tvb, offset);
12630                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12631                 offset += 2;
12632
12633                 /* param displacement is zero here */
12634                 pd = 0;
12635
12636                 /* data count */
12637                 dc = tvb_get_letohs(tvb, offset);
12638                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12639                 offset += 2;
12640
12641                 /* data offset */
12642                 od = tvb_get_letohs(tvb, offset);
12643                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12644                 offset += 2;
12645
12646                 /* data displacement is zero here */
12647                 dd = 0;
12648
12649                 /* setup count */
12650                 sc = tvb_get_guint8(tvb, offset);
12651                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12652                 offset += 1;
12653
12654                 /* reserved byte */
12655                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12656                 offset += 1;
12657
12658                 /* this is where the setup bytes, if any start */
12659                 so = offset;
12660                 sl = sc*2;
12661
12662                 /* if there were any setup bytes, decode them */
12663                 if(sc){
12664                         switch(si->cmd){
12665
12666                         case SMB_COM_TRANSACTION2:
12667                                 /* TRANSACTION2 only has one setup word and
12668                                    that is the subcommand code.
12669
12670                                    XXX - except for TRANS2_FSCTL
12671                                    and TRANS2_IOCTL. */
12672                                 subcmd = tvb_get_letohs(tvb, offset);
12673                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12674                                     tvb, offset, 2, subcmd);
12675                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12676                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12677                                             val_to_str(subcmd, trans2_cmd_vals,
12678                                                 "Unknown (0x%02x)"));
12679                                 }
12680                                 if (!si->unidir) {
12681                                         if(!pinfo->fd->flags.visited && si->sip){
12682                                                 /*
12683                                                  * Allocate a new
12684                                                  * smb_transact2_info_t
12685                                                  * structure.
12686                                                  */
12687                                                 t2i = se_alloc(sizeof(smb_transact2_info_t));
12688                                                 t2i->subcmd = subcmd;
12689                                                 t2i->info_level = -1;
12690                                                 t2i->resume_keys = FALSE;
12691                                                 t2i->name = NULL;
12692                                                 si->sip->extra_info = t2i;
12693                                                 si->sip->extra_info_type = SMB_EI_T2I;
12694                                         }
12695                                 }
12696
12697                                 /*
12698                                  * XXX - process TRANS2_FSCTL and
12699                                  * TRANS2_IOCTL setup words here.
12700                                  */
12701                                 break;
12702
12703                         case SMB_COM_TRANSACTION:
12704                                 /* TRANSACTION setup words processed below */
12705                                 break;
12706                         }
12707
12708                         offset += sl;
12709                 }
12710         }
12711
12712         BYTE_COUNT;
12713
12714         if(wc!=8){
12715                 /* primary request */
12716                 /* name is NULL if transaction2 */
12717                 if(si->cmd == SMB_COM_TRANSACTION){
12718                         /* Transaction Name */
12719                         an = get_unicode_or_ascii_string(tvb, &offset,
12720                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12721                         if (an == NULL)
12722                                 goto endofcommand;
12723                         tvb_ensure_bytes_exist(tvb, offset, an_len);
12724                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12725                                 offset, an_len, an);
12726                         COUNT_BYTES(an_len);
12727                 }
12728         }
12729
12730         /*
12731          * The pipe or mailslot arguments for Transaction start with
12732          * the first setup word (or where the first setup word would
12733          * be if there were any setup words), and run to the current
12734          * offset (which could mean that there aren't any).
12735          */
12736         spo = so;
12737         spc = offset - spo;
12738
12739         /* parameters */
12740         if(po>offset){
12741                 /* We have some initial padding bytes.
12742                 */
12743                 padcnt = po-offset;
12744                 if (padcnt > bc)
12745                         padcnt = bc;
12746                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
12747                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12748                 COUNT_BYTES(padcnt);
12749         }
12750         if(pc){
12751                 CHECK_BYTE_COUNT(pc);
12752                 switch(si->cmd) {
12753
12754                 case SMB_COM_TRANSACTION2:
12755                         /* TRANSACTION2 parameters*/
12756                         offset = dissect_transaction2_request_parameters(tvb,
12757                             pinfo, tree, offset, subcmd, pc);
12758                         bc -= pc;
12759                         break;
12760
12761                 case SMB_COM_TRANSACTION:
12762                         /* TRANSACTION parameters processed below */
12763                         COUNT_BYTES(pc);
12764                         break;
12765                 }
12766         }
12767
12768         /* data */
12769         if(od>offset){
12770                 /* We have some initial padding bytes.
12771                 */
12772                 padcnt = od-offset;
12773                 if (padcnt > bc)
12774                         padcnt = bc;
12775                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
12776                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12777                 COUNT_BYTES(padcnt);
12778         }
12779         if(dc){
12780                 CHECK_BYTE_COUNT(dc);
12781                 switch(si->cmd){
12782
12783                 case SMB_COM_TRANSACTION2:
12784                         /* TRANSACTION2 data*/
12785                         offset = dissect_transaction2_request_data(tvb, pinfo,
12786                             tree, offset, subcmd, dc);
12787                         bc -= dc;
12788                         break;
12789
12790                 case SMB_COM_TRANSACTION:
12791                         /* TRANSACTION data processed below */
12792                         COUNT_BYTES(dc);
12793                         break;
12794                 }
12795         }
12796
12797         /*TRANSACTION request parameters */
12798         if(si->cmd==SMB_COM_TRANSACTION){
12799                 /*XXX replace this block with a function and use that one
12800                      for both requests/responses*/
12801                 if(dd==0){
12802                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12803                         tvbuff_t *sp_tvb, *pd_tvb;
12804
12805                         if(pc>0){
12806                                 if(pc>tvb_length_remaining(tvb, po)){
12807                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12808                                 } else {
12809                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12810                                 }
12811                         } else {
12812                                 p_tvb = NULL;
12813                         }
12814                         if(dc>0){
12815                                 if(dc>tvb_length_remaining(tvb, od)){
12816                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12817                                 } else {
12818                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12819                                 }
12820                         } else {
12821                                 d_tvb = NULL;
12822                         }
12823                         if(sl){
12824                                 if(sl>tvb_length_remaining(tvb, so)){
12825                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12826                                 } else {
12827                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12828                                 }
12829                         } else {
12830                                 s_tvb = NULL;
12831                         }
12832
12833                         if (!si->unidir) {
12834                                 if(!pinfo->fd->flags.visited && si->sip){
12835                                         /*
12836                                          * Allocate a new smb_transact_info_t
12837                                          * structure.
12838                                          */
12839                                         tri = se_alloc(sizeof(smb_transact_info_t));
12840                                         tri->subcmd = -1;
12841                                         tri->trans_subcmd = -1;
12842                                         tri->function = -1;
12843                                         tri->fid = -1;
12844                                         tri->lanman_cmd = 0;
12845                                         tri->param_descrip = NULL;
12846                                         tri->data_descrip = NULL;
12847                                         tri->aux_data_descrip = NULL;
12848                                         tri->info_level = -1;
12849                                         si->sip->extra_info = tri;
12850                                         si->sip->extra_info_type = SMB_EI_TRI;
12851                                 } else {
12852                                         /*
12853                                          * We already filled the structure
12854                                          * in; don't bother doing so again.
12855                                          */
12856                                         tri = NULL;
12857                                 }
12858                         } else {
12859                                 /*
12860                                  * This is a unidirectional message, for
12861                                  * which there will be no reply; don't
12862                                  * bother allocating an "smb_transact_info_t"
12863                                  * structure for it.
12864                                  */
12865                                 tri = NULL;
12866                         }
12867                         dissected_trans = FALSE;
12868                         if (an == NULL)
12869                                 goto endofcommand;
12870                         if(strncmp("\\PIPE\\", an, 6) == 0){
12871                                 if (tri != NULL)
12872                                         tri->subcmd=TRANSACTION_PIPE;
12873
12874                                 /*
12875                                  * A tvbuff containing the setup words and
12876                                  * the pipe path.
12877                                  */
12878                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12879
12880                                 /*
12881                                  * A tvbuff containing the parameters and the
12882                                  * data.
12883                                  */
12884                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12885
12886                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12887                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12888                                     top_tree);
12889
12890                                 /* In case we did not see the TreeConnect call,
12891                                    store this TID here as well as a IPC TID 
12892                                    so we know that future Read/Writes to this 
12893                                    TID is (probably) DCERPC.
12894                                 */
12895                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
12896                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
12897                                 }
12898                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
12899                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12900                                 if (tri != NULL)
12901                                         tri->subcmd=TRANSACTION_MAILSLOT;
12902
12903                                 /*
12904                                  * A tvbuff containing the setup words and
12905                                  * the mailslot path.
12906                                  */
12907                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12908                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12909                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12910                         }
12911                         if (!dissected_trans)
12912                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12913                 } else {
12914                         if(check_col(pinfo->cinfo, COL_INFO)){
12915                                 col_append_str(pinfo->cinfo, COL_INFO,
12916                                         "[transact continuation]");
12917                         }
12918                 }
12919         }
12920
12921         END_OF_SMB
12922
12923         return offset;
12924 }
12925
12926
12927
12928 static int
12929 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12930     int offset, guint16 *bcp, gboolean *trunc)
12931 {
12932         int fn_len;
12933         const char *fn;
12934         int old_offset = offset;
12935         proto_item *item = NULL;
12936         proto_tree *tree = NULL;
12937         smb_info_t *si;
12938         smb_transact2_info_t *t2i;
12939         gboolean resume_keys = FALSE;
12940
12941         si = (smb_info_t *)pinfo->private_data;
12942         DISSECTOR_ASSERT(si);
12943
12944         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
12945                 t2i = si->sip->extra_info;
12946                 if (t2i != NULL)
12947                         resume_keys = t2i->resume_keys;
12948         }
12949
12950         if(parent_tree){
12951                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12952                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12953                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12954                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12955         }
12956
12957         if (resume_keys) {
12958                 /* resume key */
12959                 CHECK_BYTE_COUNT_SUBR(4);
12960                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12961                 COUNT_BYTES_SUBR(4);
12962         }
12963
12964         /* create time */
12965         CHECK_BYTE_COUNT_SUBR(4);
12966         offset = dissect_smb_datetime(tvb, tree, offset,
12967                 hf_smb_create_time,
12968                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12969         *bcp -= 4;
12970
12971         /* access time */
12972         CHECK_BYTE_COUNT_SUBR(4);
12973         offset = dissect_smb_datetime(tvb, tree, offset,
12974                 hf_smb_access_time,
12975                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12976         *bcp -= 4;
12977
12978         /* last write time */
12979         CHECK_BYTE_COUNT_SUBR(4);
12980         offset = dissect_smb_datetime(tvb, tree, offset,
12981                 hf_smb_last_write_time,
12982                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12983         *bcp -= 4;
12984
12985         /* data size */
12986         CHECK_BYTE_COUNT_SUBR(4);
12987         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12988         COUNT_BYTES_SUBR(4);
12989
12990         /* allocation size */
12991         CHECK_BYTE_COUNT_SUBR(4);
12992         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12993         COUNT_BYTES_SUBR(4);
12994
12995         /* File Attributes */
12996         CHECK_BYTE_COUNT_SUBR(2);
12997         offset = dissect_file_attributes(tvb, tree, offset, 2);
12998         *bcp -= 2;
12999
13000         /* file name len */
13001         CHECK_BYTE_COUNT_SUBR(1);
13002         fn_len = tvb_get_guint8(tvb, offset);
13003         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13004         COUNT_BYTES_SUBR(1);
13005         if (si->unicode)
13006                 fn_len += 2;    /* include terminating '\0' */
13007         else
13008                 fn_len++;       /* include terminating '\0' */
13009
13010         /* file name */
13011         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13012         CHECK_STRING_SUBR(fn);
13013         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13014                 fn);
13015         COUNT_BYTES_SUBR(fn_len);
13016
13017         if (check_col(pinfo->cinfo, COL_INFO)) {
13018                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13019                     format_text(fn, strlen(fn)));
13020         }
13021
13022         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13023         proto_item_set_len(item, offset-old_offset);
13024
13025         *trunc = FALSE;
13026         return offset;
13027 }
13028
13029 static int
13030 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13031     int offset, guint16 *bcp, gboolean *trunc)
13032 {
13033         int fn_len;
13034         const char *fn;
13035         int old_offset = offset;
13036         proto_item *item = NULL;
13037         proto_tree *tree = NULL;
13038         smb_info_t *si;
13039         smb_transact2_info_t *t2i;
13040         gboolean resume_keys = FALSE;
13041
13042         si = (smb_info_t *)pinfo->private_data;
13043         DISSECTOR_ASSERT(si);
13044
13045         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13046                 t2i = si->sip->extra_info;
13047                 if (t2i != NULL)
13048                         resume_keys = t2i->resume_keys;
13049         }
13050
13051         if(parent_tree){
13052                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13053                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13054                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13055                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13056         }
13057
13058         if (resume_keys) {
13059                 /* resume key */
13060                 CHECK_BYTE_COUNT_SUBR(4);
13061                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13062                 COUNT_BYTES_SUBR(4);
13063         }
13064
13065         /* create time */
13066         CHECK_BYTE_COUNT_SUBR(4);
13067         offset = dissect_smb_datetime(tvb, tree, offset,
13068                 hf_smb_create_time,
13069                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13070         *bcp -= 4;
13071
13072         /* access time */
13073         CHECK_BYTE_COUNT_SUBR(4);
13074         offset = dissect_smb_datetime(tvb, tree, offset,
13075                 hf_smb_access_time,
13076                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13077         *bcp -= 4;
13078
13079         /* last write time */
13080         CHECK_BYTE_COUNT_SUBR(4);
13081         offset = dissect_smb_datetime(tvb, tree, offset,
13082                 hf_smb_last_write_time,
13083                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13084         *bcp -= 4;
13085
13086         /* data size */
13087         CHECK_BYTE_COUNT_SUBR(4);
13088         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13089         COUNT_BYTES_SUBR(4);
13090
13091         /* allocation size */
13092         CHECK_BYTE_COUNT_SUBR(4);
13093         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13094         COUNT_BYTES_SUBR(4);
13095
13096         /* File Attributes */
13097         CHECK_BYTE_COUNT_SUBR(2);
13098         offset = dissect_file_attributes(tvb, tree, offset, 2);
13099         *bcp -= 2;
13100
13101         /* ea length */
13102         CHECK_BYTE_COUNT_SUBR(4);
13103         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13104         COUNT_BYTES_SUBR(4);
13105
13106         /* file name len */
13107         CHECK_BYTE_COUNT_SUBR(1);
13108         fn_len = tvb_get_guint8(tvb, offset);
13109         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13110         COUNT_BYTES_SUBR(1);
13111         if (si->unicode)
13112                 fn_len += 2;    /* include terminating '\0' */
13113         else
13114                 fn_len++;       /* include terminating '\0' */
13115
13116         /* file name */
13117         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13118         CHECK_STRING_SUBR(fn);
13119         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13120                 fn);
13121         COUNT_BYTES_SUBR(fn_len);
13122
13123         if (check_col(pinfo->cinfo, COL_INFO)) {
13124                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13125                     format_text(fn, strlen(fn)));
13126         }
13127
13128         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13129         proto_item_set_len(item, offset-old_offset);
13130
13131         *trunc = FALSE;
13132         return offset;
13133 }
13134
13135 static int
13136 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13137     int offset, guint16 *bcp, gboolean *trunc)
13138 {
13139         int fn_len;
13140         const char *fn;
13141         int old_offset = offset;
13142         proto_item *item = NULL;
13143         proto_tree *tree = NULL;
13144         smb_info_t *si;
13145         guint32 neo;
13146         int padcnt;
13147
13148         si = (smb_info_t *)pinfo->private_data;
13149         DISSECTOR_ASSERT(si);
13150
13151         if(parent_tree){
13152                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13153                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13154                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13155                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13156         }
13157
13158         /*
13159          * We assume that the presence of a next entry offset implies the
13160          * absence of a resume key, as appears to be the case for 4.3.4.6.
13161          */
13162
13163         /* next entry offset */
13164         CHECK_BYTE_COUNT_SUBR(4);
13165         neo = tvb_get_letohl(tvb, offset);
13166         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13167         COUNT_BYTES_SUBR(4);
13168
13169         /* file index */
13170         CHECK_BYTE_COUNT_SUBR(4);
13171         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13172         COUNT_BYTES_SUBR(4);
13173
13174         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13175         if (*trunc) {
13176           return offset;
13177         }
13178
13179         /* end of file */
13180         CHECK_BYTE_COUNT_SUBR(8);
13181         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13182         COUNT_BYTES_SUBR(8);
13183
13184         /* allocation size */
13185         CHECK_BYTE_COUNT_SUBR(8);
13186         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13187         COUNT_BYTES_SUBR(8);
13188
13189         /* Extended File Attributes */
13190         CHECK_BYTE_COUNT_SUBR(4);
13191         offset = dissect_file_ext_attr(tvb, tree, offset);
13192         *bcp -= 4;
13193
13194         /* file name len */
13195         CHECK_BYTE_COUNT_SUBR(4);
13196         fn_len = tvb_get_letohl(tvb, offset);
13197         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13198         COUNT_BYTES_SUBR(4);
13199
13200         /* file name */
13201         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13202         CHECK_STRING_SUBR(fn);
13203         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13204                 fn);
13205         COUNT_BYTES_SUBR(fn_len);
13206
13207         if (check_col(pinfo->cinfo, COL_INFO)) {
13208                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13209                     format_text(fn, strlen(fn)));
13210         }
13211
13212         /* skip to next structure */
13213         if(neo){
13214                 padcnt = (old_offset + neo) - offset;
13215                 if (padcnt < 0) {
13216                         /*
13217                          * XXX - this is bogus; flag it?
13218                          */
13219                         padcnt = 0;
13220                 }
13221                 if (padcnt != 0) {
13222                         CHECK_BYTE_COUNT_SUBR(padcnt);
13223                         COUNT_BYTES_SUBR(padcnt);
13224                 }
13225         }
13226
13227         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13228         proto_item_set_len(item, offset-old_offset);
13229
13230         *trunc = FALSE;
13231         return offset;
13232 }
13233
13234 static int
13235 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13236     int offset, guint16 *bcp, gboolean *trunc)
13237 {
13238         int fn_len;
13239         const char *fn;
13240         int old_offset = offset;
13241         proto_item *item = NULL;
13242         proto_tree *tree = NULL;
13243         smb_info_t *si;
13244         guint32 neo;
13245         int padcnt;
13246
13247         si = (smb_info_t *)pinfo->private_data;
13248         DISSECTOR_ASSERT(si);
13249
13250         if(parent_tree){
13251                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13252                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13253                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13254                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13255         }
13256
13257         /*
13258          * We assume that the presence of a next entry offset implies the
13259          * absence of a resume key, as appears to be the case for 4.3.4.6.
13260          */
13261
13262         /* next entry offset */
13263         CHECK_BYTE_COUNT_SUBR(4);
13264         neo = tvb_get_letohl(tvb, offset);
13265         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13266         COUNT_BYTES_SUBR(4);
13267
13268         /* file index */
13269         CHECK_BYTE_COUNT_SUBR(4);
13270         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13271         COUNT_BYTES_SUBR(4);
13272
13273         /* standard 8-byte timestamps */
13274         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13275         if (*trunc) {
13276           return offset;
13277         }
13278
13279         /* end of file */
13280         CHECK_BYTE_COUNT_SUBR(8);
13281         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13282         COUNT_BYTES_SUBR(8);
13283
13284         /* allocation size */
13285         CHECK_BYTE_COUNT_SUBR(8);
13286         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13287         COUNT_BYTES_SUBR(8);
13288
13289         /* Extended File Attributes */
13290         CHECK_BYTE_COUNT_SUBR(4);
13291         offset = dissect_file_ext_attr(tvb, tree, offset);
13292         *bcp -= 4;
13293
13294         /* file name len */
13295         CHECK_BYTE_COUNT_SUBR(4);
13296         fn_len = tvb_get_letohl(tvb, offset);
13297         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13298         COUNT_BYTES_SUBR(4);
13299
13300         /* ea length */
13301         CHECK_BYTE_COUNT_SUBR(4);
13302         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13303         COUNT_BYTES_SUBR(4);
13304
13305         /* file name */
13306         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13307         CHECK_STRING_SUBR(fn);
13308         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13309                 fn);
13310         COUNT_BYTES_SUBR(fn_len);
13311
13312         if (check_col(pinfo->cinfo, COL_INFO)) {
13313                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13314                     format_text(fn, strlen(fn)));
13315         }
13316
13317         /* skip to next structure */
13318         if(neo){
13319                 padcnt = (old_offset + neo) - offset;
13320                 if (padcnt < 0) {
13321                         /*
13322                          * XXX - this is bogus; flag it?
13323                          */
13324                         padcnt = 0;
13325                 }
13326                 if (padcnt != 0) {
13327                         CHECK_BYTE_COUNT_SUBR(padcnt);
13328                         COUNT_BYTES_SUBR(padcnt);
13329                 }
13330         }
13331
13332         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13333         proto_item_set_len(item, offset-old_offset);
13334
13335         *trunc = FALSE;
13336         return offset;
13337 }
13338
13339 static int
13340 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13341     int offset, guint16 *bcp, gboolean *trunc)
13342 {
13343         int fn_len, sfn_len;
13344         const char *fn, *sfn;
13345         int old_offset = offset;
13346         proto_item *item = NULL;
13347         proto_tree *tree = NULL;
13348         smb_info_t *si;
13349         guint32 neo;
13350         int padcnt;
13351
13352         si = (smb_info_t *)pinfo->private_data;
13353         DISSECTOR_ASSERT(si);
13354
13355         if(parent_tree){
13356                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13357                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13358                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13359                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13360         }
13361
13362         /*
13363          * XXX - I have not seen any of these that contain a resume
13364          * key, even though some of the requests had the "return resume
13365          * key" flag set.
13366          */
13367
13368         /* next entry offset */
13369         CHECK_BYTE_COUNT_SUBR(4);
13370         neo = tvb_get_letohl(tvb, offset);
13371         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13372         COUNT_BYTES_SUBR(4);
13373
13374         /* file index */
13375         CHECK_BYTE_COUNT_SUBR(4);
13376         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13377         COUNT_BYTES_SUBR(4);
13378
13379         /* dissect standard 8-byte timestamps */
13380         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13381         if (*trunc) {
13382           return offset;
13383         }
13384
13385         /* end of file */
13386         CHECK_BYTE_COUNT_SUBR(8);
13387         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13388         COUNT_BYTES_SUBR(8);
13389
13390         /* allocation size */
13391         CHECK_BYTE_COUNT_SUBR(8);
13392         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13393         COUNT_BYTES_SUBR(8);
13394
13395         /* Extended File Attributes */
13396         CHECK_BYTE_COUNT_SUBR(4);
13397         offset = dissect_file_ext_attr(tvb, tree, offset);
13398         *bcp -= 4;
13399
13400         /* file name len */
13401         CHECK_BYTE_COUNT_SUBR(4);
13402         fn_len = tvb_get_letohl(tvb, offset);
13403         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13404         COUNT_BYTES_SUBR(4);
13405
13406         /*
13407          * EA length.
13408          *
13409          * XXX - in one captures, this has the topmost bit set, and the
13410          * rest of the bits have the value 7.  Is the topmost bit being
13411          * set some indication that the value *isn't* the length of
13412          * the EAs?
13413          */
13414         CHECK_BYTE_COUNT_SUBR(4);
13415         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13416         COUNT_BYTES_SUBR(4);
13417
13418         /* short file name len */
13419         CHECK_BYTE_COUNT_SUBR(1);
13420         sfn_len = tvb_get_guint8(tvb, offset);
13421         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
13422         COUNT_BYTES_SUBR(1);
13423
13424         /* reserved byte */
13425         CHECK_BYTE_COUNT_SUBR(1);
13426         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13427         COUNT_BYTES_SUBR(1);
13428
13429         /* short file name - it's not always in Unicode */
13430         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
13431         CHECK_STRING_SUBR(sfn);
13432         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
13433                 sfn);
13434         COUNT_BYTES_SUBR(24);
13435
13436         /* file name */
13437         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13438         CHECK_STRING_SUBR(fn);
13439         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13440                 fn);
13441         COUNT_BYTES_SUBR(fn_len);
13442
13443         if (check_col(pinfo->cinfo, COL_INFO)) {
13444                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13445                     format_text(fn, strlen(fn)));
13446         }
13447
13448         /* skip to next structure */
13449         if(neo){
13450                 padcnt = (old_offset + neo) - offset;
13451                 if (padcnt < 0) {
13452                         /*
13453                          * XXX - this is bogus; flag it?
13454                          */
13455                         padcnt = 0;
13456                 }
13457                 if (padcnt != 0) {
13458                         CHECK_BYTE_COUNT_SUBR(padcnt);
13459                         COUNT_BYTES_SUBR(padcnt);
13460                 }
13461         }
13462
13463         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13464         proto_item_set_len(item, offset-old_offset);
13465
13466         *trunc = FALSE;
13467         return offset;
13468 }
13469
13470 static int
13471 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13472     int offset, guint16 *bcp, gboolean *trunc)
13473 {
13474         int fn_len;
13475         const char *fn;
13476         int old_offset = offset;
13477         proto_item *item = NULL;
13478         proto_tree *tree = NULL;
13479         smb_info_t *si;
13480         guint32 neo;
13481         int padcnt;
13482
13483         si = (smb_info_t *)pinfo->private_data;
13484         DISSECTOR_ASSERT(si);
13485
13486         if(parent_tree){
13487                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13488                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13489                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13490                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13491         }
13492
13493         /*
13494          * We assume that the presence of a next entry offset implies the
13495          * absence of a resume key, as appears to be the case for 4.3.4.6.
13496          */
13497
13498         /* next entry offset */
13499         CHECK_BYTE_COUNT_SUBR(4);
13500         neo = tvb_get_letohl(tvb, offset);
13501         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13502         COUNT_BYTES_SUBR(4);
13503
13504         /* file index */
13505         CHECK_BYTE_COUNT_SUBR(4);
13506         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13507         COUNT_BYTES_SUBR(4);
13508
13509         /* file name len */
13510         CHECK_BYTE_COUNT_SUBR(4);
13511         fn_len = tvb_get_letohl(tvb, offset);
13512         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13513         COUNT_BYTES_SUBR(4);
13514
13515         /* file name */
13516         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13517         CHECK_STRING_SUBR(fn);
13518         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13519                 fn);
13520         COUNT_BYTES_SUBR(fn_len);
13521
13522         if (check_col(pinfo->cinfo, COL_INFO)) {
13523                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13524                     format_text(fn, strlen(fn)));
13525         }
13526
13527         /* skip to next structure */
13528         if(neo){
13529                 padcnt = (old_offset + neo) - offset;
13530                 if (padcnt < 0) {
13531                         /*
13532                          * XXX - this is bogus; flag it?
13533                          */
13534                         padcnt = 0;
13535                 }
13536                 if (padcnt != 0) {
13537                         CHECK_BYTE_COUNT_SUBR(padcnt);
13538                         COUNT_BYTES_SUBR(padcnt);
13539                 }
13540         }
13541
13542         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13543         proto_item_set_len(item, offset-old_offset);
13544
13545         *trunc = FALSE;
13546         return offset;
13547 }
13548
13549 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13550
13551 static int
13552 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13553                 proto_tree *tree, int offset, guint16 *bcp,
13554                 gboolean *trunc)
13555 {
13556         smb_info_t *si = pinfo->private_data;
13557         const char *fn;
13558         int fn_len;
13559
13560         DISSECTOR_ASSERT(si);
13561
13562         /* NextEntryOffset */
13563         CHECK_BYTE_COUNT_SUBR(4);
13564         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13565         COUNT_BYTES_SUBR(4);
13566         
13567         /* ResumeKey */
13568         CHECK_BYTE_COUNT_SUBR(4);
13569         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13570         COUNT_BYTES_SUBR(4);
13571
13572         /* End of file (file size) */
13573         CHECK_BYTE_COUNT_SUBR(8);
13574         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13575         COUNT_BYTES_SUBR(8);
13576
13577         /* Number of bytes */
13578         CHECK_BYTE_COUNT_SUBR(8);
13579         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13580         COUNT_BYTES_SUBR(8);
13581
13582         /* Last status change */
13583         CHECK_BYTE_COUNT_SUBR(8);
13584         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13585         *bcp -= 8;
13586
13587         /* Last access time */
13588         CHECK_BYTE_COUNT_SUBR(8);
13589         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13590         *bcp -= 8;
13591
13592         /* Last modification time */
13593         CHECK_BYTE_COUNT_SUBR(8);
13594         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13595         *bcp -= 8;
13596
13597         /* File owner uid */
13598         CHECK_BYTE_COUNT_SUBR(8);
13599         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13600         COUNT_BYTES_SUBR(8);
13601
13602         /* File group gid */
13603         CHECK_BYTE_COUNT_SUBR(8);
13604         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13605         COUNT_BYTES_SUBR(8);
13606
13607         /* File type */
13608         CHECK_BYTE_COUNT_SUBR(4);
13609         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13610         COUNT_BYTES_SUBR(4);
13611
13612         /* Major device number */
13613         CHECK_BYTE_COUNT_SUBR(8);
13614         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13615         COUNT_BYTES_SUBR(8);
13616
13617         /* Minor device number */
13618         CHECK_BYTE_COUNT_SUBR(8);
13619         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13620         COUNT_BYTES_SUBR(8);
13621
13622         /* Unique id */
13623         CHECK_BYTE_COUNT_SUBR(8);
13624         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13625         COUNT_BYTES_SUBR(8);
13626
13627         /* Permissions */
13628         CHECK_BYTE_COUNT_SUBR(8);
13629         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13630         COUNT_BYTES_SUBR(8);
13631
13632         /* Nlinks */
13633         CHECK_BYTE_COUNT_SUBR(8);
13634         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13635         COUNT_BYTES_SUBR(8);
13636
13637         /* Name */
13638
13639         fn = get_unicode_or_ascii_string(
13640                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13641
13642         CHECK_STRING_SUBR(fn);
13643         proto_tree_add_string(
13644                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13645         COUNT_BYTES_SUBR(fn_len);
13646
13647         /* Pad to 4 bytes */
13648
13649         if (offset % 4)
13650                 offset += 4 - (offset % 4);
13651
13652         *trunc = FALSE;
13653         return offset;
13654 }
13655
13656 /*dissect the data block for TRANS2_FIND_FIRST2*/
13657 static int
13658 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13659     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13660 {
13661         smb_info_t *si;
13662
13663         if(!*bcp){
13664                 return offset;
13665         }
13666
13667         si = (smb_info_t *)pinfo->private_data;
13668         DISSECTOR_ASSERT(si);
13669
13670         switch(si->info_level){
13671         case 1:         /*Info Standard*/
13672                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13673                     trunc);
13674                 break;
13675         case 2:         /*Info Query EA Size*/
13676                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13677                     trunc);
13678                 break;
13679         case 3:         /*Info Query EAs From List same as
13680                                 InfoQueryEASize*/
13681                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13682                     trunc);
13683                 break;
13684         case 0x0101:    /*Find File Directory Info*/
13685                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13686                     trunc);
13687                 break;
13688         case 0x0102:    /*Find File Full Directory Info*/
13689                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13690                     trunc);
13691                 break;
13692         case 0x0103:    /*Find File Names Info*/
13693                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13694                     trunc);
13695                 break;
13696         case 0x0104:    /*Find File Both Directory Info*/
13697                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13698                     trunc);
13699                 break;
13700         case 0x0202:    /*Find File UNIX*/
13701                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13702                     trunc);
13703                 break;
13704         default:        /* unknown info level */
13705                 *trunc = FALSE;
13706                 break;
13707         }
13708         return offset;
13709 }
13710
13711
13712 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
13713 static int
13714 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13715 {
13716         guint32 mask;
13717         proto_item *item = NULL;
13718         proto_tree *tree = NULL;
13719
13720         mask = tvb_get_letohl(tvb, offset);
13721
13722         if(parent_tree){
13723                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13724                         "FS Attributes: 0x%08x", mask);
13725                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13726         }
13727
13728         /* case sensitive search */
13729         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13730                 tvb, offset, 4, mask);
13731         /* case preserved names */
13732         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13733                 tvb, offset, 4, mask);
13734         /* unicode on disk */
13735         proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
13736                 tvb, offset, 4, mask);
13737         /* persistent acls */
13738         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13739                 tvb, offset, 4, mask);
13740         /* file compression */
13741         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13742                 tvb, offset, 4, mask);
13743         /* volume quotas */
13744         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13745                 tvb, offset, 4, mask);
13746         /* sparse files */
13747         proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
13748                 tvb, offset, 4, mask);
13749         /* reparse points */
13750         proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
13751                 tvb, offset, 4, mask);
13752         /* remote storage */
13753         proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
13754                 tvb, offset, 4, mask);
13755         /* lfn apis */
13756         proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
13757                 tvb, offset, 4, mask);
13758         /* volume is compressed */
13759         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13760                 tvb, offset, 4, mask);
13761         /* support oids */
13762         proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
13763                 tvb, offset, 4, mask);
13764         /* encryption */
13765         proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
13766                 tvb, offset, 4, mask);
13767         /* named streams */
13768         proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
13769                 tvb, offset, 4, mask);
13770         /* read only volume */
13771         proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
13772                 tvb, offset, 4, mask);
13773
13774
13775         offset += 4;
13776         return offset;
13777 }
13778
13779
13780 static int
13781 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13782 {
13783         guint32 mask;
13784         proto_item *item = NULL;
13785         proto_tree *tree = NULL;
13786
13787         mask = tvb_get_letohl(tvb, offset);
13788
13789         if(parent_tree){
13790                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13791                         "Device Characteristics: 0x%08x", mask);
13792                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13793         }
13794
13795         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13796                 tvb, offset, 4, mask);
13797         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13798                 tvb, offset, 4, mask);
13799         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13800                 tvb, offset, 4, mask);
13801         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13802                 tvb, offset, 4, mask);
13803         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13804                 tvb, offset, 4, mask);
13805         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13806                 tvb, offset, 4, mask);
13807         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13808                 tvb, offset, 4, mask);
13809
13810         offset += 4;
13811         return offset;
13812 }
13813
13814 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13815
13816 static const true_false_string tfs_smb_mac_access_ctrl = {
13817   "Macintosh Access Control Supported",
13818   "Macintosh Access Control Not Supported"
13819 };
13820
13821 static const true_false_string tfs_smb_mac_getset_comments = {
13822   "Macintosh Get & Set Comments Supported",
13823   "Macintosh Get & Set Comments Not Supported"
13824 };
13825
13826 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13827   "Macintosh Get & Set Desktop Database Info Supported",
13828   "Macintosh Get & Set Desktop Database Info Supported"
13829 };
13830
13831 static const true_false_string tfs_smb_mac_unique_ids = {
13832   "Macintosh Unique IDs Supported",
13833   "Macintosh Unique IDs Not Supported"
13834 };
13835
13836 static const true_false_string tfs_smb_mac_streams = {
13837   "Macintosh and Streams Extensions Not Supported",
13838   "Macintosh and Streams Extensions Supported"
13839 };
13840
13841 int
13842 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
13843 {
13844         int fn_len, vll;
13845         const char *fn;
13846
13847         /* create time */
13848         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13849         offset = dissect_nt_64bit_time(tvb, tree, offset,
13850                 hf_smb_create_time);
13851         *bcp -= 8;
13852
13853         /* volume serial number */
13854         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13855         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13856         COUNT_BYTES_TRANS_SUBR(4);
13857
13858         /* volume label length */
13859         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13860         vll = tvb_get_letohl(tvb, offset);
13861         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13862         COUNT_BYTES_TRANS_SUBR(4);
13863
13864         /* 2 reserved bytes */
13865         CHECK_BYTE_COUNT_TRANS_SUBR(2);
13866         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13867         COUNT_BYTES_TRANS_SUBR(2);
13868
13869         /* label */
13870         fn_len = vll;
13871         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
13872         CHECK_STRING_TRANS_SUBR(fn);
13873         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13874                 fn);
13875         COUNT_BYTES_TRANS_SUBR(fn_len);
13876
13877         return offset;
13878 }
13879
13880 int
13881 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13882 {
13883         /* allocation size */
13884         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13885         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13886         COUNT_BYTES_TRANS_SUBR(8);
13887
13888         /* free allocation units */
13889         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13890         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13891         COUNT_BYTES_TRANS_SUBR(8);
13892
13893         /* sectors per unit */
13894         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13895         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13896         COUNT_BYTES_TRANS_SUBR(4);
13897
13898         /* bytes per sector */
13899         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13900         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13901         COUNT_BYTES_TRANS_SUBR(4);
13902
13903         return offset;
13904 }
13905
13906 int
13907 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13908 {
13909         /* device type */
13910         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13911         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13912         COUNT_BYTES_TRANS_SUBR(4);
13913
13914         /* device characteristics */
13915         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13916         offset = dissect_device_characteristics(tvb, tree, offset);
13917         *bcp -= 4;
13918
13919         return offset;
13920 }
13921
13922 int
13923 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
13924 {
13925         int fn_len, fnl;
13926         const char *fn;
13927
13928         /* FS attributes */
13929         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13930         offset = dissect_fs_attributes(tvb, tree, offset);
13931         *bcp -= 4;
13932
13933         /* max name len */
13934         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13935         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13936         COUNT_BYTES_TRANS_SUBR(4);
13937
13938         /* fs name length */
13939         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13940         fnl = tvb_get_letohl(tvb, offset);
13941         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13942         COUNT_BYTES_TRANS_SUBR(4);
13943
13944         /* label */
13945         fn_len = fnl;
13946         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
13947         CHECK_STRING_TRANS_SUBR(fn);
13948         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13949                 fn);
13950         COUNT_BYTES_TRANS_SUBR(fn_len);
13951
13952         return offset;
13953 }
13954
13955 int
13956 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
13957 {
13958         CHECK_BYTE_COUNT_TRANS_SUBR(64);
13959
13960         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
13961
13962         COUNT_BYTES_TRANS_SUBR(64);
13963
13964         return offset;
13965 }
13966
13967 int
13968 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13969 {
13970         /* allocation size */
13971         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13972         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13973         COUNT_BYTES_TRANS_SUBR(8);
13974
13975         /* caller free allocation units */
13976         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13977         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13978         COUNT_BYTES_TRANS_SUBR(8);
13979
13980         /* actual free allocation units */
13981         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13982         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13983         COUNT_BYTES_TRANS_SUBR(8);
13984
13985         /* sectors per unit */
13986         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13987         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13988         COUNT_BYTES_TRANS_SUBR(4);
13989
13990         /* bytes per sector */
13991         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13992         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13993         COUNT_BYTES_TRANS_SUBR(4);
13994
13995         return offset;
13996 }
13997
13998 static int
13999 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
14000     int offset, guint16 *bcp)
14001 {
14002         smb_info_t *si;
14003         int fn_len, vll;
14004         const char *fn;
14005         guint support = 0;
14006         proto_item *item = NULL;
14007         proto_tree *ti = NULL;
14008
14009         if(!*bcp){
14010                 return offset;
14011         }
14012
14013         si = (smb_info_t *)pinfo->private_data;
14014         DISSECTOR_ASSERT(si);
14015
14016         switch(si->info_level){
14017         case 1:         /* SMB_INFO_ALLOCATION */
14018                 /* filesystem id */
14019                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14020                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
14021                 COUNT_BYTES_TRANS_SUBR(4);
14022
14023                 /* sectors per unit */
14024                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14025                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14026                 COUNT_BYTES_TRANS_SUBR(4);
14027
14028                 /* units */
14029                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14030                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
14031                 COUNT_BYTES_TRANS_SUBR(4);
14032
14033                 /* avail units */
14034                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14035                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
14036                 COUNT_BYTES_TRANS_SUBR(4);
14037
14038                 /* bytes per sector, only 16bit integer here */
14039                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14040                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14041                 COUNT_BYTES_TRANS_SUBR(2);
14042
14043                 break;
14044         case 2:         /* SMB_INFO_VOLUME */
14045                 /* volume serial number */
14046                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14047                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14048                 COUNT_BYTES_TRANS_SUBR(4);
14049
14050                 /* volume label length, only one byte here */
14051                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
14052                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
14053                 COUNT_BYTES_TRANS_SUBR(1);
14054
14055                 /* label */
14056                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
14057                 CHECK_STRING_TRANS_SUBR(fn);
14058                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14059                         fn);
14060                 COUNT_BYTES_TRANS_SUBR(fn_len);
14061
14062                 break;
14063         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
14064         case 1002:      /* SMB_FS_LABEL_INFORMATION */
14065                 /* volume label length */
14066                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14067                 vll = tvb_get_letohl(tvb, offset);
14068                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14069                 COUNT_BYTES_TRANS_SUBR(4);
14070
14071                 /* label */
14072                 fn_len = vll;
14073                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14074                 CHECK_STRING_TRANS_SUBR(fn);
14075                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14076                         fn);
14077                 COUNT_BYTES_TRANS_SUBR(fn_len);
14078
14079                 break;
14080         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
14081         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
14082                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14083                 break;
14084         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
14085         case 1003:      /* SMB_FS_SIZE_INFORMATION */
14086                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14087                 break;
14088         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
14089         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
14090                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
14091                 break;
14092         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
14093         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
14094                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14095                 break;
14096         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
14097                 proto_item *item = NULL;
14098                 proto_tree *subtree = NULL;
14099                 guint32 caps_lo, caps_hi;
14100
14101                 /* MajorVersionNumber */
14102                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14103                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
14104                 COUNT_BYTES_TRANS_SUBR(2);
14105
14106                 /* MinorVersionNumber */
14107                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14108                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
14109                 COUNT_BYTES_TRANS_SUBR(2);
14110
14111                 /* Capability */
14112
14113                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14114
14115                 caps_lo = tvb_get_letohl(tvb, offset);
14116                 caps_hi = tvb_get_letohl(tvb, offset + 4);
14117
14118                 if (tree) {
14119                         item = proto_tree_add_text(
14120                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
14121                                 caps_hi, caps_lo);
14122                         subtree = proto_item_add_subtree(
14123                                 item, ett_smb_unix_capabilities);
14124                 }
14125
14126                 proto_tree_add_boolean(
14127                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
14128                         caps_lo);
14129
14130                 proto_tree_add_boolean(
14131                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
14132                         caps_lo);
14133
14134                 COUNT_BYTES_TRANS_SUBR(8);
14135
14136                 break;
14137         }
14138         case 0x301:     /* MAC_QUERY_FS_INFO */
14139                 /* Create time */
14140                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14141                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
14142                 *bcp -= 8;
14143                 /* Modify Time */
14144                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14145                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
14146                 *bcp -= 8;
14147                 /* Backup Time */
14148                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14149                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
14150                 *bcp -= 8;
14151                 /* Allocation blocks */
14152                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14153                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
14154                                     offset,
14155                                     4, TRUE);
14156                 COUNT_BYTES_TRANS_SUBR(4);
14157                 /* Allocation Block Size */
14158                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14159                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
14160                                     offset, 4, TRUE);
14161                 COUNT_BYTES_TRANS_SUBR(4);
14162                 /* Free Block Count */
14163                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14164                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
14165                                     offset, 4, TRUE);
14166                 COUNT_BYTES_TRANS_SUBR(4);
14167                 /* Finder Info ... */
14168                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
14169                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
14170                                             offset, 32,
14171                                             tvb_get_ptr(tvb, offset,32),
14172                                             "Finder Info: %s",
14173                                             tvb_format_text(tvb, offset, 32));
14174                 COUNT_BYTES_TRANS_SUBR(32);
14175                 /* Number Files */
14176                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14177                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
14178                                     offset, 4, TRUE);
14179                 COUNT_BYTES_TRANS_SUBR(4);
14180                 /* Number of Root Directories */
14181                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14182                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
14183                                     offset, 4, TRUE);
14184                 COUNT_BYTES_TRANS_SUBR(4);
14185                 /* Number of files */
14186                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14187                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
14188                                     offset, 4, TRUE);
14189                 COUNT_BYTES_TRANS_SUBR(4);
14190                 /* Dir Count */
14191                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14192                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
14193                                     offset, 4, TRUE);
14194                 COUNT_BYTES_TRANS_SUBR(4);
14195                 /* Mac Support Flags */
14196                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14197                 support = tvb_get_ntohl(tvb, offset);
14198                 item = proto_tree_add_text(tree, tvb, offset, 4,
14199                                            "Mac Support Flags: 0x%08x", support);
14200                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
14201                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
14202                                        tvb, offset, 4, support);
14203                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
14204                                        tvb, offset, 4, support);
14205                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
14206                                        tvb, offset, 4, support);
14207                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
14208                                        tvb, offset, 4, support);
14209                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
14210                                        tvb, offset, 4, support);
14211                 COUNT_BYTES_TRANS_SUBR(4);
14212                 break;
14213         case 1006:      /* QUERY_FS_QUOTA_INFO */
14214                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
14215                 break;
14216         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
14217                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14218                 break;
14219         case 1008: /* Query Object ID */ {
14220                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
14221                 break;
14222             }
14223         }
14224
14225         return offset;
14226 }
14227
14228 static int
14229 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
14230     proto_tree *parent_tree)
14231 {
14232         proto_item *item = NULL;
14233         proto_tree *tree = NULL;
14234         smb_info_t *si;
14235         smb_transact2_info_t *t2i;
14236         int count;
14237         gboolean trunc;
14238         int offset = 0;
14239         guint16 dc;
14240
14241         dc = tvb_reported_length(tvb);
14242
14243         si = (smb_info_t *)pinfo->private_data;
14244         DISSECTOR_ASSERT(si);
14245
14246         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14247                 t2i = si->sip->extra_info;
14248         else
14249                 t2i = NULL;
14250
14251         if(parent_tree){
14252                 if (t2i != NULL && t2i->subcmd != -1) {
14253                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14254                                 "%s Data",
14255                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14256                                         "Unknown (0x%02x)"));
14257                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
14258                 } else {
14259                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14260                                 "Unknown Transaction2 Data");
14261                 }
14262         }
14263
14264         if (t2i == NULL) {
14265                 offset += dc;
14266                 return offset;
14267         }
14268         switch(t2i->subcmd){
14269         case 0x00:      /*TRANS2_OPEN2*/
14270                 /* XXX not implemented yet. See SNIA doc */
14271                 break;
14272         case 0x01:      /*TRANS2_FIND_FIRST2*/
14273                 /* returned data */
14274                 count = si->info_count;
14275
14276         if(count == -1) {
14277             break;
14278         }
14279                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14280                         col_append_fstr(pinfo->cinfo, COL_INFO,
14281                         ", Files:");
14282                 }
14283
14284                 while(count--){
14285                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14286                                 offset, &dc, &trunc);
14287                         if (trunc)
14288                                 break;
14289                 }
14290                 break;
14291         case 0x02:      /*TRANS2_FIND_NEXT2*/
14292                 /* returned data */
14293                 count = si->info_count;
14294
14295         if(count == -1) {
14296             break;
14297         }
14298                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14299                         col_append_fstr(pinfo->cinfo, COL_INFO,
14300                         ", Files:");
14301                 }
14302
14303                 while(count--){
14304                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14305                                 offset, &dc, &trunc);
14306                         if (trunc)
14307                                 break;
14308                 }
14309                 break;
14310         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14311                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
14312                 break;
14313         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14314                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14315                 break;
14316         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14317                 /* no data in this response */
14318                 break;
14319         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14320                 /* identical to QUERY_PATH_INFO */
14321                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14322                 break;
14323         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14324                 /* no data in this response */
14325                 break;
14326         case 0x09:      /*TRANS2_FSCTL*/
14327                 /* XXX dont know how to dissect this one (yet)*/
14328
14329                 /*
14330                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14331                  * Extensions Version 3.0, Document Version 1.11,
14332                  * July 19, 1990" says this this contains a
14333                  * "File system specific return data block".
14334                  * (That means we may not be able to dissect it in any
14335                  * case.)
14336                  */
14337                 break;
14338         case 0x0a:      /*TRANS2_IOCTL2*/
14339                 /* XXX dont know how to dissect this one (yet)*/
14340
14341                 /*
14342                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14343                  * Extensions Version 3.0, Document Version 1.11,
14344                  * July 19, 1990" says this this contains a
14345                  * "Device/function specific return data block".
14346                  * (That means we may not be able to dissect it in any
14347                  * case.)
14348                  */
14349                 break;
14350         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14351                 /* XXX dont know how to dissect this one (yet)*/
14352
14353                 /*
14354                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14355                  * Extensions Version 3.0, Document Version 1.11,
14356                  * July 19, 1990" says this this contains "the level
14357                  * dependent information about the changes which
14358                  * occurred".
14359                  */
14360                 break;
14361         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14362                 /* XXX dont know how to dissect this one (yet)*/
14363
14364                 /*
14365                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14366                  * Extensions Version 3.0, Document Version 1.11,
14367                  * July 19, 1990" says this this contains "the level
14368                  * dependent information about the changes which
14369                  * occurred".
14370                  */
14371                 break;
14372         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14373                 /* no data in this response */
14374                 break;
14375         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14376                 /* XXX dont know how to dissect this one (yet)*/
14377                 break;
14378         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14379                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
14380                 break;
14381         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14382                 /* the SNIA spec appears to say the response has no data */
14383                 break;
14384         case -1:
14385                 /*
14386                  * We don't know what the matching request was; don't
14387                  * bother putting anything else into the tree for the data.
14388                  */
14389                 offset += dc;
14390                 dc = 0;
14391                 break;
14392         }
14393
14394         /* ooops there were data we didnt know how to process */
14395         if(dc != 0){
14396                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
14397                 offset += dc;
14398         }
14399
14400         return offset;
14401 }
14402
14403
14404 static void
14405 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14406 {
14407         proto_item *item = NULL;
14408         proto_tree *tree = NULL;
14409         smb_info_t *si;
14410         smb_transact2_info_t *t2i;
14411         guint16 fid;
14412         int lno;
14413         int offset = 0;
14414         int pc;
14415
14416         pc = tvb_reported_length(tvb);
14417
14418         si = (smb_info_t *)pinfo->private_data;
14419         DISSECTOR_ASSERT(si);
14420
14421         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14422                 t2i = si->sip->extra_info;
14423         else
14424                 t2i = NULL;
14425
14426         if(parent_tree){
14427                 if (t2i != NULL && t2i->subcmd != -1) {
14428                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14429                                 "%s Parameters",
14430                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14431                                                 "Unknown (0x%02x)"));
14432                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
14433                 } else {
14434                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14435                                 "Unknown Transaction2 Parameters");
14436                 }
14437         }
14438
14439         if (t2i == NULL) {
14440                 offset += pc;
14441                 return;
14442         }
14443         switch(t2i->subcmd){
14444         case 0x00:      /*TRANS2_OPEN2*/
14445                 /* fid */
14446                 fid = tvb_get_letohs(tvb, offset);
14447                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
14448                 offset += 2;
14449
14450                 /*
14451                  * XXX - Microsoft Networks SMB File Sharing Protocol
14452                  * Extensions Version 3.0, Document Version 1.11,
14453                  * July 19, 1990 says that the file attributes, create
14454                  * time (which it says is the last modification time),
14455                  * data size, granted access, file type, and IPC state
14456                  * are returned only if bit 0 is set in the open flags,
14457                  * and that the EA length is returned only if bit 3
14458                  * is set in the open flags.  Does that mean that,
14459                  * at least in that SMB dialect, those fields are not
14460                  * present in the reply parameters if the bits in
14461                  * question aren't set?
14462                  */
14463
14464                 /* File Attributes */
14465                 offset = dissect_file_attributes(tvb, tree, offset, 2);
14466
14467                 /* create time */
14468                 offset = dissect_smb_datetime(tvb, tree, offset,
14469                         hf_smb_create_time,
14470                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
14471
14472                 /* data size */
14473                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
14474                 offset += 4;
14475
14476                 /* granted access */
14477                 offset = dissect_access(tvb, tree, offset, "Granted");
14478
14479                 /* File Type */
14480                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
14481                 offset += 2;
14482
14483                 /* IPC State */
14484                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
14485
14486                 /* open_action */
14487                 offset = dissect_open_action(tvb, tree, offset);
14488
14489                 /* server unique file ID */
14490                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
14491                 offset += 4;
14492
14493                 /* ea error offset, only a 16 bit integer here */
14494                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14495                 offset += 2;
14496
14497                 /* ea length */
14498                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
14499                 offset += 4;
14500
14501                 break;
14502         case 0x01:      /*TRANS2_FIND_FIRST2*/
14503                 /* Find First2 information level */
14504                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
14505
14506                 /* sid */
14507                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
14508                 offset += 2;
14509
14510                 /* search count */
14511                 si->info_count = tvb_get_letohs(tvb, offset);
14512                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14513                 offset += 2;
14514
14515                 /* end of search */
14516                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14517                 offset += 2;
14518
14519                 /* ea error offset, only a 16 bit integer here */
14520                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14521                 offset += 2;
14522
14523                 /* last name offset */
14524                 lno = tvb_get_letohs(tvb, offset);
14525                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14526                 offset += 2;
14527
14528                 break;
14529         case 0x02:      /*TRANS2_FIND_NEXT2*/
14530                 /* search count */
14531                 si->info_count = tvb_get_letohs(tvb, offset);
14532                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14533                 offset += 2;
14534
14535                 /* end of search */
14536                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14537                 offset += 2;
14538
14539                 /* ea_error_offset, only a 16 bit integer here*/
14540                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14541                 offset += 2;
14542
14543                 /* last name offset */
14544                 lno = tvb_get_letohs(tvb, offset);
14545                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14546                 offset += 2;
14547
14548                 break;
14549         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14550                 /* no parameter block here */
14551                 break;
14552         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14553                 /* ea_error_offset, only a 16 bit integer here*/
14554                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14555                 offset += 2;
14556
14557                 break;
14558         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14559                 /* ea_error_offset, only a 16 bit integer here*/
14560                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14561                 offset += 2;
14562
14563                 break;
14564         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14565                 /* ea_error_offset, only a 16 bit integer here*/
14566                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14567                 offset += 2;
14568
14569                 break;
14570         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14571                 /* ea_error_offset, only a 16 bit integer here*/
14572                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14573                 offset += 2;
14574
14575                 break;
14576         case 0x09:      /*TRANS2_FSCTL*/
14577                 /* XXX dont know how to dissect this one (yet)*/
14578
14579                 /*
14580                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14581                  * Extensions Version 3.0, Document Version 1.11,
14582                  * July 19, 1990" says this this contains a
14583                  * "File system specific return parameter block".
14584                  * (That means we may not be able to dissect it in any
14585                  * case.)
14586                  */
14587                 break;
14588         case 0x0a:      /*TRANS2_IOCTL2*/
14589                 /* XXX dont know how to dissect this one (yet)*/
14590
14591                 /*
14592                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14593                  * Extensions Version 3.0, Document Version 1.11,
14594                  * July 19, 1990" says this this contains a
14595                  * "Device/function specific return parameter block".
14596                  * (That means we may not be able to dissect it in any
14597                  * case.)
14598                  */
14599                 break;
14600         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14601                 /* Find Notify information level */
14602                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14603
14604                 /* Monitor handle */
14605                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14606                 offset += 2;
14607
14608                 /* Change count */
14609                 si->info_count = tvb_get_letohs(tvb, offset);
14610                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14611                 offset += 2;
14612
14613                 /* ea_error_offset, only a 16 bit integer here*/
14614                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14615                 offset += 2;
14616
14617                 break;
14618         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14619                 /* Find Notify information level */
14620                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14621
14622                 /* Change count */
14623                 si->info_count = tvb_get_letohs(tvb, offset);
14624                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14625                 offset += 2;
14626
14627                 /* ea_error_offset, only a 16 bit integer here*/
14628                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14629                 offset += 2;
14630
14631                 break;
14632         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14633                 /* ea error offset, only a 16 bit integer here */
14634                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14635                 offset += 2;
14636
14637                 break;
14638         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14639                 /* XXX dont know how to dissect this one (yet)*/
14640                 break;
14641         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14642                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14643                 break;
14644         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14645                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14646                 break;
14647         case -1:
14648                 /*
14649                  * We don't know what the matching request was; don't
14650                  * bother putting anything else into the tree for the data.
14651                  */
14652                 offset += pc;
14653                 break;
14654         }
14655
14656         /* ooops there were data we didnt know how to process */
14657         if(offset<pc){
14658                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14659                 offset += pc-offset;
14660         }
14661 }
14662
14663
14664 static int
14665 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14666 {
14667         guint8 sc, wc;
14668         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14669         smb_info_t *si;
14670         smb_transact2_info_t *t2i = NULL;
14671         guint16 bc;
14672         int padcnt;
14673         gboolean dissected_trans;
14674         fragment_data *r_fd = NULL;
14675         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14676         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14677         gboolean save_fragmented;
14678         proto_item *item;
14679
14680         si = (smb_info_t *)pinfo->private_data;
14681         DISSECTOR_ASSERT(si);
14682
14683         switch(si->cmd){
14684         case SMB_COM_TRANSACTION2:
14685                 /* transaction2 */
14686                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
14687                         t2i = si->sip->extra_info;
14688                 } else
14689                         t2i = NULL;
14690                 if (t2i == NULL) {
14691                         /*
14692                          * We didn't see the matching request, so we don't
14693                          * know what type of transaction this is.
14694                          */
14695                         proto_tree_add_text(tree, tvb, 0, 0,
14696                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14697                         if (check_col(pinfo->cinfo, COL_INFO)) {
14698                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14699                         }
14700                 } else {
14701                         si->info_level = t2i->info_level;
14702                         if (t2i->subcmd == -1) {
14703                                 /*
14704                                  * We didn't manage to extract the subcommand
14705                                  * from the matching request (perhaps because
14706                                  * the frame was short), so we don't know what
14707                                  * type of transaction this is.
14708                                  */
14709                                 proto_tree_add_text(tree, tvb, 0, 0,
14710                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14711                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14712                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14713                                 }
14714                         } else {
14715                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14716                                 /* FIND_FIRST2 */
14717                                 if(t2i && t2i->subcmd==0x0001){
14718                                         item=proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
14719                                         PROTO_ITEM_SET_GENERATED(item);
14720                                         if(t2i->name){
14721                                                 item=proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
14722                                                 PROTO_ITEM_SET_GENERATED(item);
14723                                         }
14724                                 }
14725
14726                                 /* QUERY_PATH_INFORMATION */
14727                                 if(t2i && t2i->subcmd==0x0005){
14728                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
14729                                         PROTO_ITEM_SET_GENERATED(item);
14730                                         if(t2i->name){
14731                                                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
14732                                                 PROTO_ITEM_SET_GENERATED(item);
14733                                         }
14734                                 }
14735                                 /* QUERY_FILE_INFORMATION */
14736                                 if(t2i && t2i->subcmd==0x0007){
14737                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
14738                                         PROTO_ITEM_SET_GENERATED(item);
14739                                 }
14740                                 /* QUERY_FS_INFORMATION */
14741                                 if(t2i && t2i->subcmd==0x0003){
14742                                         item=proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
14743                                         PROTO_ITEM_SET_GENERATED(item);
14744                                 }
14745
14746                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14747                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14748                                                 val_to_str(t2i->subcmd,
14749                                                         trans2_cmd_vals,
14750                                                         "<unknown (0x%02x)>"));
14751                                 }
14752                         }
14753                 }
14754                 break;
14755         }
14756
14757         WORD_COUNT;
14758
14759         /* total param count, only a 16bit integer here */
14760         tp = tvb_get_letohs(tvb, offset);
14761         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14762         offset += 2;
14763
14764         /* total data count, only a 16 bit integer here */
14765         td = tvb_get_letohs(tvb, offset);
14766         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14767         offset += 2;
14768
14769         /* 2 reserved bytes */
14770         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14771         offset += 2;
14772
14773         /* param count */
14774         pc = tvb_get_letohs(tvb, offset);
14775         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14776         offset += 2;
14777
14778         /* param offset */
14779         po = tvb_get_letohs(tvb, offset);
14780         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14781         offset += 2;
14782
14783         /* param disp */
14784         pd = tvb_get_letohs(tvb, offset);
14785         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14786         offset += 2;
14787
14788         /* data count */
14789         dc = tvb_get_letohs(tvb, offset);
14790         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14791         offset += 2;
14792
14793         /* data offset */
14794         od = tvb_get_letohs(tvb, offset);
14795         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14796         offset += 2;
14797
14798         /* data disp */
14799         dd = tvb_get_letohs(tvb, offset);
14800         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14801         offset += 2;
14802
14803         /* setup count */
14804         sc = tvb_get_guint8(tvb, offset);
14805         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14806         offset += 1;
14807
14808         /* reserved byte */
14809         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14810         offset += 1;
14811
14812
14813         /* if there were any setup bytes, put them in a tvb for later */
14814         if(sc){
14815                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14816                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14817                 } else {
14818                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14819                 }
14820                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14821         } else {
14822                 s_tvb = NULL;
14823                 sp_tvb=NULL;
14824         }
14825         offset += 2*sc;
14826
14827
14828         BYTE_COUNT;
14829
14830
14831         /* reassembly of SMB Transaction data payload.
14832            In this section we do reassembly of both the data and parameters
14833            blocks of the SMB transaction command.
14834         */
14835         save_fragmented = pinfo->fragmented;
14836         /* do we need reassembly? */
14837         if( (td!=dc) || (tp!=pc) ){
14838                 /* oh yeah, either data or parameter section needs
14839                    reassembly
14840                 */
14841                 pinfo->fragmented = TRUE;
14842                 if(smb_trans_reassembly){
14843                         /* ...and we were told to do reassembly */
14844                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14845                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14846                                                              po, pc, pd, td+tp);
14847
14848                         }
14849                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14850                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14851                                                              od, dc, dd+tp, td+tp);
14852                         }
14853                 }
14854         }
14855
14856         /* if we got a reassembled fd structure from the reassembly routine we must
14857            create pd_tvb from it
14858         */
14859         if(r_fd){
14860         proto_item *frag_tree_item;
14861
14862                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14863                                              r_fd->datalen);
14864                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14865                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14866                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
14867         }
14868
14869
14870         if(pd_tvb){
14871                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14872                 if(tp){
14873                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14874                 }
14875                 if(td){
14876                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14877                 }
14878         } else {
14879                 /* It was not reassembled. Do as best as we can.
14880                  * in this case we always try to dissect the stuff if
14881                  * data and param displacement is 0. i.e. for the first
14882                  * (and maybe only) packet.
14883                  */
14884                 if( (pd==0) && (dd==0) ){
14885                         int min;
14886                         int reported_min;
14887                         min = MIN(pc,tvb_length_remaining(tvb,po));
14888                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14889                         if(min && reported_min) {
14890                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14891                         }
14892                         min = MIN(dc,tvb_length_remaining(tvb,od));
14893                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14894                         if(min && reported_min) {
14895                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14896                         }
14897                         /*
14898                          * A tvbuff containing the parameters
14899                          * and the data.
14900                          * XXX - check pc and dc as well?
14901                          */
14902                         if (tvb_length_remaining(tvb, po)){
14903                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14904                         }
14905                 }
14906         }
14907
14908
14909
14910         /* parameters */
14911         if(po>offset){
14912                 /* We have some padding bytes.
14913                 */
14914                 padcnt = po-offset;
14915                 if (padcnt > bc)
14916                         padcnt = bc;
14917                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14918                 COUNT_BYTES(padcnt);
14919         }
14920         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14921                 /* TRANSACTION2 parameters*/
14922                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14923         }
14924         COUNT_BYTES(pc);
14925
14926
14927         /* data */
14928         if(od>offset){
14929                 /* We have some initial padding bytes.
14930                 */
14931                 padcnt = od-offset;
14932                 if (padcnt > bc)
14933                         padcnt = bc;
14934                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14935                 COUNT_BYTES(padcnt);
14936         }
14937         /*
14938          * If the data count is bigger than the count of bytes
14939          * remaining, clamp it so that the count of bytes remaining
14940          * doesn't go negative.
14941          */
14942         if (dc > bc)
14943                 dc = bc;
14944         COUNT_BYTES(dc);
14945
14946
14947
14948         /* from now on, everything is in separate tvbuffs so we dont count
14949            the bytes with COUNT_BYTES any more.
14950            neither do we reference offset any more (which by now points to the
14951            first byte AFTER this PDU */
14952
14953
14954         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14955                 /* TRANSACTION2 parameters*/
14956                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14957         }
14958
14959
14960         if(si->cmd==SMB_COM_TRANSACTION){
14961                 smb_transact_info_t *tri;
14962
14963                 dissected_trans = FALSE;
14964                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_TRI)
14965                         tri = si->sip->extra_info;
14966                 else
14967                         tri = NULL;
14968                 if (tri != NULL) {
14969                         switch(tri->subcmd){
14970
14971                         case TRANSACTION_PIPE:
14972                                 /* This function is safe to call for
14973                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14974                                    know them at this point.
14975                                    It's also safe to call if "p_tvb"
14976                                    or "d_tvb" are null.
14977                                 */
14978                                 if( pd_tvb) {
14979                                         dissected_trans = dissect_pipe_smb(
14980                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14981                                                 d_tvb, NULL, pinfo, top_tree);
14982                                 }
14983                                 break;
14984
14985                         case TRANSACTION_MAILSLOT:
14986                                 /* This one should be safe to call
14987                                    even if s_tvb and sp_tvb is NULL
14988                                 */
14989                                 if(d_tvb){
14990                                         dissected_trans = dissect_mailslot_smb(
14991                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14992                                                 top_tree);
14993                                 }
14994                                 break;
14995                         }
14996                 }
14997                 if (!dissected_trans) {
14998                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14999                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
15000                 }
15001         }
15002
15003
15004         if( (p_tvb==0) && (d_tvb==0) ){
15005                 if(check_col(pinfo->cinfo, COL_INFO)){
15006                         col_append_str(pinfo->cinfo, COL_INFO,
15007                                        "[transact continuation]");
15008                 }
15009         }
15010
15011         pinfo->fragmented = save_fragmented;
15012         END_OF_SMB
15013
15014         return offset;
15015 }
15016
15017
15018 static int
15019 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15020 {
15021         guint8 wc;
15022         guint16 bc;
15023
15024         WORD_COUNT;
15025
15026         /* Monitor handle */
15027         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
15028         offset += 2;
15029
15030         BYTE_COUNT;
15031
15032         END_OF_SMB
15033
15034         return offset;
15035 }
15036
15037 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15038    END Transaction/Transaction2 Primary and secondary requests
15039    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15040
15041
15042 static int
15043 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15044 {
15045         guint8 wc;
15046         guint16 bc;
15047
15048         WORD_COUNT;
15049
15050         if (wc != 0) {
15051                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
15052                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
15053                 offset += wc*2;
15054         }
15055
15056         BYTE_COUNT;
15057
15058         if (bc != 0) {
15059                 tvb_ensure_bytes_exist(tvb, offset, bc);
15060                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
15061                 offset += bc;
15062                 bc = 0;
15063         }
15064
15065         END_OF_SMB
15066
15067         return offset;
15068 }
15069
15070 typedef struct _smb_function {
15071        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15072        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15073 } smb_function;
15074
15075 static smb_function smb_dissector[256] = {
15076   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
15077   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
15078   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
15079   /* 0x03 Create File*/  {dissect_create_file_request, dissect_create_file_response},
15080   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
15081   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
15082   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
15083   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_rename_file_response},
15084   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
15085   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
15086   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
15087   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
15088   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
15089   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
15090   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
15091   /* 0x0f Create New*/  {dissect_create_file_request, dissect_create_new_response},
15092
15093   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
15094   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
15095   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
15096   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
15097   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
15098   /* 0x15 */  {dissect_unknown, dissect_unknown},
15099   /* 0x16 */  {dissect_unknown, dissect_unknown},
15100   /* 0x17 */  {dissect_unknown, dissect_unknown},
15101   /* 0x18 */  {dissect_unknown, dissect_unknown},
15102   /* 0x19 */  {dissect_unknown, dissect_unknown},
15103   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
15104   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
15105   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
15106   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
15107   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
15108   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
15109
15110   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
15111   /* 0x21 */  {dissect_unknown, dissect_unknown},
15112   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
15113   /* 0x23 Query Info2*/  {dissect_query_information2_request, dissect_query_information2_response},
15114   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
15115   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
15116   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15117   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
15118   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
15119   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
15120   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
15121   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
15122   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
15123   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
15124   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
15125   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
15126
15127   /* 0x30 */  {dissect_unknown, dissect_unknown},
15128   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
15129   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
15130   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15131   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
15132   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
15133   /* 0x36 */  {dissect_unknown, dissect_unknown},
15134   /* 0x37 */  {dissect_unknown, dissect_unknown},
15135   /* 0x38 */  {dissect_unknown, dissect_unknown},
15136   /* 0x39 */  {dissect_unknown, dissect_unknown},
15137   /* 0x3a */  {dissect_unknown, dissect_unknown},
15138   /* 0x3b */  {dissect_unknown, dissect_unknown},
15139   /* 0x3c */  {dissect_unknown, dissect_unknown},
15140   /* 0x3d */  {dissect_unknown, dissect_unknown},
15141   /* 0x3e */  {dissect_unknown, dissect_unknown},
15142   /* 0x3f */  {dissect_unknown, dissect_unknown},
15143
15144   /* 0x40 */  {dissect_unknown, dissect_unknown},
15145   /* 0x41 */  {dissect_unknown, dissect_unknown},
15146   /* 0x42 */  {dissect_unknown, dissect_unknown},
15147   /* 0x43 */  {dissect_unknown, dissect_unknown},
15148   /* 0x44 */  {dissect_unknown, dissect_unknown},
15149   /* 0x45 */  {dissect_unknown, dissect_unknown},
15150   /* 0x46 */  {dissect_unknown, dissect_unknown},
15151   /* 0x47 */  {dissect_unknown, dissect_unknown},
15152   /* 0x48 */  {dissect_unknown, dissect_unknown},
15153   /* 0x49 */  {dissect_unknown, dissect_unknown},
15154   /* 0x4a */  {dissect_unknown, dissect_unknown},
15155   /* 0x4b */  {dissect_unknown, dissect_unknown},
15156   /* 0x4c */  {dissect_unknown, dissect_unknown},
15157   /* 0x4d */  {dissect_unknown, dissect_unknown},
15158   /* 0x4e */  {dissect_unknown, dissect_unknown},
15159   /* 0x4f */  {dissect_unknown, dissect_unknown},
15160
15161   /* 0x50 */  {dissect_unknown, dissect_unknown},
15162   /* 0x51 */  {dissect_unknown, dissect_unknown},
15163   /* 0x52 */  {dissect_unknown, dissect_unknown},
15164   /* 0x53 */  {dissect_unknown, dissect_unknown},
15165   /* 0x54 */  {dissect_unknown, dissect_unknown},
15166   /* 0x55 */  {dissect_unknown, dissect_unknown},
15167   /* 0x56 */  {dissect_unknown, dissect_unknown},
15168   /* 0x57 */  {dissect_unknown, dissect_unknown},
15169   /* 0x58 */  {dissect_unknown, dissect_unknown},
15170   /* 0x59 */  {dissect_unknown, dissect_unknown},
15171   /* 0x5a */  {dissect_unknown, dissect_unknown},
15172   /* 0x5b */  {dissect_unknown, dissect_unknown},
15173   /* 0x5c */  {dissect_unknown, dissect_unknown},
15174   /* 0x5d */  {dissect_unknown, dissect_unknown},
15175   /* 0x5e */  {dissect_unknown, dissect_unknown},
15176   /* 0x5f */  {dissect_unknown, dissect_unknown},
15177
15178   /* 0x60 */  {dissect_unknown, dissect_unknown},
15179   /* 0x61 */  {dissect_unknown, dissect_unknown},
15180   /* 0x62 */  {dissect_unknown, dissect_unknown},
15181   /* 0x63 */  {dissect_unknown, dissect_unknown},
15182   /* 0x64 */  {dissect_unknown, dissect_unknown},
15183   /* 0x65 */  {dissect_unknown, dissect_unknown},
15184   /* 0x66 */  {dissect_unknown, dissect_unknown},
15185   /* 0x67 */  {dissect_unknown, dissect_unknown},
15186   /* 0x68 */  {dissect_unknown, dissect_unknown},
15187   /* 0x69 */  {dissect_unknown, dissect_unknown},
15188   /* 0x6a */  {dissect_unknown, dissect_unknown},
15189   /* 0x6b */  {dissect_unknown, dissect_unknown},
15190   /* 0x6c */  {dissect_unknown, dissect_unknown},
15191   /* 0x6d */  {dissect_unknown, dissect_unknown},
15192   /* 0x6e */  {dissect_unknown, dissect_unknown},
15193   /* 0x6f */  {dissect_unknown, dissect_unknown},
15194
15195   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
15196   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
15197   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
15198   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
15199   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
15200   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
15201   /* 0x76 */  {dissect_unknown, dissect_unknown},
15202   /* 0x77 */  {dissect_unknown, dissect_unknown},
15203   /* 0x78 */  {dissect_unknown, dissect_unknown},
15204   /* 0x79 */  {dissect_unknown, dissect_unknown},
15205   /* 0x7a */  {dissect_unknown, dissect_unknown},
15206   /* 0x7b */  {dissect_unknown, dissect_unknown},
15207   /* 0x7c */  {dissect_unknown, dissect_unknown},
15208   /* 0x7d */  {dissect_unknown, dissect_unknown},
15209   /* 0x7e */  {dissect_unknown, dissect_unknown},
15210   /* 0x7f */  {dissect_unknown, dissect_unknown},
15211
15212   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
15213   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
15214   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
15215   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
15216   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
15217   /* 0x85 */  {dissect_unknown, dissect_unknown},
15218   /* 0x86 */  {dissect_unknown, dissect_unknown},
15219   /* 0x87 */  {dissect_unknown, dissect_unknown},
15220   /* 0x88 */  {dissect_unknown, dissect_unknown},
15221   /* 0x89 */  {dissect_unknown, dissect_unknown},
15222   /* 0x8a */  {dissect_unknown, dissect_unknown},
15223   /* 0x8b */  {dissect_unknown, dissect_unknown},
15224   /* 0x8c */  {dissect_unknown, dissect_unknown},
15225   /* 0x8d */  {dissect_unknown, dissect_unknown},
15226   /* 0x8e */  {dissect_unknown, dissect_unknown},
15227   /* 0x8f */  {dissect_unknown, dissect_unknown},
15228
15229   /* 0x90 */  {dissect_unknown, dissect_unknown},
15230   /* 0x91 */  {dissect_unknown, dissect_unknown},
15231   /* 0x92 */  {dissect_unknown, dissect_unknown},
15232   /* 0x93 */  {dissect_unknown, dissect_unknown},
15233   /* 0x94 */  {dissect_unknown, dissect_unknown},
15234   /* 0x95 */  {dissect_unknown, dissect_unknown},
15235   /* 0x96 */  {dissect_unknown, dissect_unknown},
15236   /* 0x97 */  {dissect_unknown, dissect_unknown},
15237   /* 0x98 */  {dissect_unknown, dissect_unknown},
15238   /* 0x99 */  {dissect_unknown, dissect_unknown},
15239   /* 0x9a */  {dissect_unknown, dissect_unknown},
15240   /* 0x9b */  {dissect_unknown, dissect_unknown},
15241   /* 0x9c */  {dissect_unknown, dissect_unknown},
15242   /* 0x9d */  {dissect_unknown, dissect_unknown},
15243   /* 0x9e */  {dissect_unknown, dissect_unknown},
15244   /* 0x9f */  {dissect_unknown, dissect_unknown},
15245
15246   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
15247   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
15248   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
15249   /* 0xa3 */  {dissect_unknown, dissect_unknown},
15250   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
15251   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
15252   /* 0xa6 */  {dissect_unknown, dissect_unknown},
15253   /* 0xa7 */  {dissect_unknown, dissect_unknown},
15254   /* 0xa8 */  {dissect_unknown, dissect_unknown},
15255   /* 0xa9 */  {dissect_unknown, dissect_unknown},
15256   /* 0xaa */  {dissect_unknown, dissect_unknown},
15257   /* 0xab */  {dissect_unknown, dissect_unknown},
15258   /* 0xac */  {dissect_unknown, dissect_unknown},
15259   /* 0xad */  {dissect_unknown, dissect_unknown},
15260   /* 0xae */  {dissect_unknown, dissect_unknown},
15261   /* 0xaf */  {dissect_unknown, dissect_unknown},
15262
15263   /* 0xb0 */  {dissect_unknown, dissect_unknown},
15264   /* 0xb1 */  {dissect_unknown, dissect_unknown},
15265   /* 0xb2 */  {dissect_unknown, dissect_unknown},
15266   /* 0xb3 */  {dissect_unknown, dissect_unknown},
15267   /* 0xb4 */  {dissect_unknown, dissect_unknown},
15268   /* 0xb5 */  {dissect_unknown, dissect_unknown},
15269   /* 0xb6 */  {dissect_unknown, dissect_unknown},
15270   /* 0xb7 */  {dissect_unknown, dissect_unknown},
15271   /* 0xb8 */  {dissect_unknown, dissect_unknown},
15272   /* 0xb9 */  {dissect_unknown, dissect_unknown},
15273   /* 0xba */  {dissect_unknown, dissect_unknown},
15274   /* 0xbb */  {dissect_unknown, dissect_unknown},
15275   /* 0xbc */  {dissect_unknown, dissect_unknown},
15276   /* 0xbd */  {dissect_unknown, dissect_unknown},
15277   /* 0xbe */  {dissect_unknown, dissect_unknown},
15278   /* 0xbf */  {dissect_unknown, dissect_unknown},
15279
15280   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_open_print_file_response},
15281   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
15282   /* 0xc2 Close Print File*/  {dissect_close_print_file_request, dissect_empty},
15283   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
15284   /* 0xc4 */  {dissect_unknown, dissect_unknown},
15285   /* 0xc5 */  {dissect_unknown, dissect_unknown},
15286   /* 0xc6 */  {dissect_unknown, dissect_unknown},
15287   /* 0xc7 */  {dissect_unknown, dissect_unknown},
15288   /* 0xc8 */  {dissect_unknown, dissect_unknown},
15289   /* 0xc9 */  {dissect_unknown, dissect_unknown},
15290   /* 0xca */  {dissect_unknown, dissect_unknown},
15291   /* 0xcb */  {dissect_unknown, dissect_unknown},
15292   /* 0xcc */  {dissect_unknown, dissect_unknown},
15293   /* 0xcd */  {dissect_unknown, dissect_unknown},
15294   /* 0xce */  {dissect_unknown, dissect_unknown},
15295   /* 0xcf */  {dissect_unknown, dissect_unknown},
15296
15297   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
15298   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
15299   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
15300   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
15301   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
15302   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
15303   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
15304   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
15305   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
15306   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
15307   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
15308   /* 0xdb */  {dissect_unknown, dissect_unknown},
15309   /* 0xdc */  {dissect_unknown, dissect_unknown},
15310   /* 0xdd */  {dissect_unknown, dissect_unknown},
15311   /* 0xde */  {dissect_unknown, dissect_unknown},
15312   /* 0xdf */  {dissect_unknown, dissect_unknown},
15313
15314   /* 0xe0 */  {dissect_unknown, dissect_unknown},
15315   /* 0xe1 */  {dissect_unknown, dissect_unknown},
15316   /* 0xe2 */  {dissect_unknown, dissect_unknown},
15317   /* 0xe3 */  {dissect_unknown, dissect_unknown},
15318   /* 0xe4 */  {dissect_unknown, dissect_unknown},
15319   /* 0xe5 */  {dissect_unknown, dissect_unknown},
15320   /* 0xe6 */  {dissect_unknown, dissect_unknown},
15321   /* 0xe7 */  {dissect_unknown, dissect_unknown},
15322   /* 0xe8 */  {dissect_unknown, dissect_unknown},
15323   /* 0xe9 */  {dissect_unknown, dissect_unknown},
15324   /* 0xea */  {dissect_unknown, dissect_unknown},
15325   /* 0xeb */  {dissect_unknown, dissect_unknown},
15326   /* 0xec */  {dissect_unknown, dissect_unknown},
15327   /* 0xed */  {dissect_unknown, dissect_unknown},
15328   /* 0xee */  {dissect_unknown, dissect_unknown},
15329   /* 0xef */  {dissect_unknown, dissect_unknown},
15330
15331   /* 0xf0 */  {dissect_unknown, dissect_unknown},
15332   /* 0xf1 */  {dissect_unknown, dissect_unknown},
15333   /* 0xf2 */  {dissect_unknown, dissect_unknown},
15334   /* 0xf3 */  {dissect_unknown, dissect_unknown},
15335   /* 0xf4 */  {dissect_unknown, dissect_unknown},
15336   /* 0xf5 */  {dissect_unknown, dissect_unknown},
15337   /* 0xf6 */  {dissect_unknown, dissect_unknown},
15338   /* 0xf7 */  {dissect_unknown, dissect_unknown},
15339   /* 0xf8 */  {dissect_unknown, dissect_unknown},
15340   /* 0xf9 */  {dissect_unknown, dissect_unknown},
15341   /* 0xfa */  {dissect_unknown, dissect_unknown},
15342   /* 0xfb */  {dissect_unknown, dissect_unknown},
15343   /* 0xfc */  {dissect_unknown, dissect_unknown},
15344   /* 0xfd */  {dissect_unknown, dissect_unknown},
15345   /* 0xfe */  {dissect_unknown, dissect_unknown},
15346   /* 0xff */  {dissect_unknown, dissect_unknown},
15347 };
15348
15349 static int
15350 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
15351 {
15352         smb_info_t *si;
15353         smb_saved_info_t *sip;
15354
15355         si = pinfo->private_data;
15356         DISSECTOR_ASSERT(si);
15357
15358         if(cmd!=0xff){
15359                 proto_item *cmd_item;
15360                 proto_tree *cmd_tree;
15361                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15362
15363                 if (check_col(pinfo->cinfo, COL_INFO)) {
15364                         if(first_pdu){
15365                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15366                                         "%s %s",
15367                                         decode_smb_name(cmd),
15368                                         (si->request)? "Request" : "Response");
15369                         } else {
15370                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15371                                         "; %s",
15372                                         decode_smb_name(cmd));
15373                         }
15374
15375                 }
15376
15377                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
15378                         "%s %s (0x%02x)",
15379                         decode_smb_name(cmd),
15380                         (si->request)?"Request":"Response",
15381                         cmd);
15382
15383                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
15384
15385                 /* we track FIDs on a per transaction basis.
15386                    if this was a request and the fid was seen in a reply
15387                    we add a "generated" fid tree for this pdu and v.v.
15388                  */
15389                 sip = si->sip;
15390                 if (sip && sip->fid) {
15391                         if( (si->request && (!sip->fid_seen_in_request))
15392                           ||((!si->request) && sip->fid_seen_in_request) ){
15393                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
15394                         }
15395                 }
15396
15397                 dissector = (si->request)?
15398                         smb_dissector[cmd].request:smb_dissector[cmd].response;
15399
15400                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
15401                 proto_item_set_end(cmd_item, tvb, offset);
15402         }
15403         return offset;
15404 }
15405
15406
15407 /* NOTE: this value_string array will also be used to access data directly by
15408  * index instead of val_to_str() since
15409  * 1, the array will always span every value from 0x00 to 0xff and
15410  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
15411  * This means that this value_string array MUST always
15412  * 1, contain all entries 0x00 to 0xff
15413  * 2, all entries must be in order.
15414  */
15415 const value_string smb_cmd_vals[] = {
15416   { 0x00, "Create Directory" },
15417   { 0x01, "Delete Directory" },
15418   { 0x02, "Open" },
15419   { 0x03, "Create" },
15420   { 0x04, "Close" },
15421   { 0x05, "Flush" },
15422   { 0x06, "Delete" },
15423   { 0x07, "Rename" },
15424   { 0x08, "Query Information" },
15425   { 0x09, "Set Information" },
15426   { 0x0A, "Read" },
15427   { 0x0B, "Write" },
15428   { 0x0C, "Lock Byte Range" },
15429   { 0x0D, "Unlock Byte Range" },
15430   { 0x0E, "Create Temp" },
15431   { 0x0F, "Create New" },
15432   { 0x10, "Check Directory" },
15433   { 0x11, "Process Exit" },
15434   { 0x12, "Seek" },
15435   { 0x13, "Lock And Read" },
15436   { 0x14, "Write And Unlock" },
15437   { 0x15, "unknown-0x15" },
15438   { 0x16, "unknown-0x16" },
15439   { 0x17, "unknown-0x17" },
15440   { 0x18, "unknown-0x18" },
15441   { 0x19, "unknown-0x19" },
15442   { 0x1A, "Read Raw" },
15443   { 0x1B, "Read MPX" },
15444   { 0x1C, "Read MPX Secondary" },
15445   { 0x1D, "Write Raw" },
15446   { 0x1E, "Write MPX" },
15447   { 0x1F, "Write MPX Secondary" },
15448   { 0x20, "Write Complete" },
15449   { 0x21, "unknown-0x21" },
15450   { 0x22, "Set Information2" },
15451   { 0x23, "Query Information2" },
15452   { 0x24, "Locking AndX" },
15453   { 0x25, "Trans" },
15454   { 0x26, "Trans Secondary" },
15455   { 0x27, "IOCTL" },
15456   { 0x28, "IOCTL Secondary" },
15457   { 0x29, "Copy" },
15458   { 0x2A, "Move" },
15459   { 0x2B, "Echo" },
15460   { 0x2C, "Write And Close" },
15461   { 0x2D, "Open AndX" },
15462   { 0x2E, "Read AndX" },
15463   { 0x2F, "Write AndX" },
15464   { 0x30, "unknown-0x30" },
15465   { 0x31, "Close And Tree Disconnect" },
15466   { 0x32, "Trans2" },
15467   { 0x33, "Trans2 Secondary" },
15468   { 0x34, "Find Close2" },
15469   { 0x35, "Find Notify Close" },
15470   { 0x36, "unknown-0x36" },
15471   { 0x37, "unknown-0x37" },
15472   { 0x38, "unknown-0x38" },
15473   { 0x39, "unknown-0x39" },
15474   { 0x3A, "unknown-0x3A" },
15475   { 0x3B, "unknown-0x3B" },
15476   { 0x3C, "unknown-0x3C" },
15477   { 0x3D, "unknown-0x3D" },
15478   { 0x3E, "unknown-0x3E" },
15479   { 0x3F, "unknown-0x3F" },
15480   { 0x40, "unknown-0x40" },
15481   { 0x41, "unknown-0x41" },
15482   { 0x42, "unknown-0x42" },
15483   { 0x43, "unknown-0x43" },
15484   { 0x44, "unknown-0x44" },
15485   { 0x45, "unknown-0x45" },
15486   { 0x46, "unknown-0x46" },
15487   { 0x47, "unknown-0x47" },
15488   { 0x48, "unknown-0x48" },
15489   { 0x49, "unknown-0x49" },
15490   { 0x4A, "unknown-0x4A" },
15491   { 0x4B, "unknown-0x4B" },
15492   { 0x4C, "unknown-0x4C" },
15493   { 0x4D, "unknown-0x4D" },
15494   { 0x4E, "unknown-0x4E" },
15495   { 0x4F, "unknown-0x4F" },
15496   { 0x50, "unknown-0x50" },
15497   { 0x51, "unknown-0x51" },
15498   { 0x52, "unknown-0x52" },
15499   { 0x53, "unknown-0x53" },
15500   { 0x54, "unknown-0x54" },
15501   { 0x55, "unknown-0x55" },
15502   { 0x56, "unknown-0x56" },
15503   { 0x57, "unknown-0x57" },
15504   { 0x58, "unknown-0x58" },
15505   { 0x59, "unknown-0x59" },
15506   { 0x5A, "unknown-0x5A" },
15507   { 0x5B, "unknown-0x5B" },
15508   { 0x5C, "unknown-0x5C" },
15509   { 0x5D, "unknown-0x5D" },
15510   { 0x5E, "unknown-0x5E" },
15511   { 0x5F, "unknown-0x5F" },
15512   { 0x60, "unknown-0x60" },
15513   { 0x61, "unknown-0x61" },
15514   { 0x62, "unknown-0x62" },
15515   { 0x63, "unknown-0x63" },
15516   { 0x64, "unknown-0x64" },
15517   { 0x65, "unknown-0x65" },
15518   { 0x66, "unknown-0x66" },
15519   { 0x67, "unknown-0x67" },
15520   { 0x68, "unknown-0x68" },
15521   { 0x69, "unknown-0x69" },
15522   { 0x6A, "unknown-0x6A" },
15523   { 0x6B, "unknown-0x6B" },
15524   { 0x6C, "unknown-0x6C" },
15525   { 0x6D, "unknown-0x6D" },
15526   { 0x6E, "unknown-0x6E" },
15527   { 0x6F, "unknown-0x6F" },
15528   { 0x70, "Tree Connect" },
15529   { 0x71, "Tree Disconnect" },
15530   { 0x72, "Negotiate Protocol" },
15531   { 0x73, "Session Setup AndX" },
15532   { 0x74, "Logoff AndX" },
15533   { 0x75, "Tree Connect AndX" },
15534   { 0x76, "unknown-0x76" },
15535   { 0x77, "unknown-0x77" },
15536   { 0x78, "unknown-0x78" },
15537   { 0x79, "unknown-0x79" },
15538   { 0x7A, "unknown-0x7A" },
15539   { 0x7B, "unknown-0x7B" },
15540   { 0x7C, "unknown-0x7C" },
15541   { 0x7D, "unknown-0x7D" },
15542   { 0x7E, "unknown-0x7E" },
15543   { 0x7F, "unknown-0x7F" },
15544   { 0x80, "Query Information Disk" },
15545   { 0x81, "Search" },
15546   { 0x82, "Find" },
15547   { 0x83, "Find Unique" },
15548   { 0x84, "Find Close" },
15549   { 0x85, "unknown-0x85" },
15550   { 0x86, "unknown-0x86" },
15551   { 0x87, "unknown-0x87" },
15552   { 0x88, "unknown-0x88" },
15553   { 0x89, "unknown-0x89" },
15554   { 0x8A, "unknown-0x8A" },
15555   { 0x8B, "unknown-0x8B" },
15556   { 0x8C, "unknown-0x8C" },
15557   { 0x8D, "unknown-0x8D" },
15558   { 0x8E, "unknown-0x8E" },
15559   { 0x8F, "unknown-0x8F" },
15560   { 0x90, "unknown-0x90" },
15561   { 0x91, "unknown-0x91" },
15562   { 0x92, "unknown-0x92" },
15563   { 0x93, "unknown-0x93" },
15564   { 0x94, "unknown-0x94" },
15565   { 0x95, "unknown-0x95" },
15566   { 0x96, "unknown-0x96" },
15567   { 0x97, "unknown-0x97" },
15568   { 0x98, "unknown-0x98" },
15569   { 0x99, "unknown-0x99" },
15570   { 0x9A, "unknown-0x9A" },
15571   { 0x9B, "unknown-0x9B" },
15572   { 0x9C, "unknown-0x9C" },
15573   { 0x9D, "unknown-0x9D" },
15574   { 0x9E, "unknown-0x9E" },
15575   { 0x9F, "unknown-0x9F" },
15576   { 0xA0, "NT Trans" },
15577   { 0xA1, "NT Trans Secondary" },
15578   { 0xA2, "NT Create AndX" },
15579   { 0xA3, "unknown-0xA3" },
15580   { 0xA4, "NT Cancel" },
15581   { 0xA5, "NT Rename" },
15582   { 0xA6, "unknown-0xA6" },
15583   { 0xA7, "unknown-0xA7" },
15584   { 0xA8, "unknown-0xA8" },
15585   { 0xA9, "unknown-0xA9" },
15586   { 0xAA, "unknown-0xAA" },
15587   { 0xAB, "unknown-0xAB" },
15588   { 0xAC, "unknown-0xAC" },
15589   { 0xAD, "unknown-0xAD" },
15590   { 0xAE, "unknown-0xAE" },
15591   { 0xAF, "unknown-0xAF" },
15592   { 0xB0, "unknown-0xB0" },
15593   { 0xB1, "unknown-0xB1" },
15594   { 0xB2, "unknown-0xB2" },
15595   { 0xB3, "unknown-0xB3" },
15596   { 0xB4, "unknown-0xB4" },
15597   { 0xB5, "unknown-0xB5" },
15598   { 0xB6, "unknown-0xB6" },
15599   { 0xB7, "unknown-0xB7" },
15600   { 0xB8, "unknown-0xB8" },
15601   { 0xB9, "unknown-0xB9" },
15602   { 0xBA, "unknown-0xBA" },
15603   { 0xBB, "unknown-0xBB" },
15604   { 0xBC, "unknown-0xBC" },
15605   { 0xBD, "unknown-0xBD" },
15606   { 0xBE, "unknown-0xBE" },
15607   { 0xBF, "unknown-0xBF" },
15608   { 0xC0, "Open Print File" },
15609   { 0xC1, "Write Print File" },
15610   { 0xC2, "Close Print File" },
15611   { 0xC3, "Get Print Queue" },
15612   { 0xC4, "unknown-0xC4" },
15613   { 0xC5, "unknown-0xC5" },
15614   { 0xC6, "unknown-0xC6" },
15615   { 0xC7, "unknown-0xC7" },
15616   { 0xC8, "unknown-0xC8" },
15617   { 0xC9, "unknown-0xC9" },
15618   { 0xCA, "unknown-0xCA" },
15619   { 0xCB, "unknown-0xCB" },
15620   { 0xCC, "unknown-0xCC" },
15621   { 0xCD, "unknown-0xCD" },
15622   { 0xCE, "unknown-0xCE" },
15623   { 0xCF, "unknown-0xCF" },
15624   { 0xD0, "Send Single Block Message" },
15625   { 0xD1, "Send Broadcast Message" },
15626   { 0xD2, "Forward User Name" },
15627   { 0xD3, "Cancel Forward" },
15628   { 0xD4, "Get Machine Name" },
15629   { 0xD5, "Send Start of Multi-block Message" },
15630   { 0xD6, "Send End of Multi-block Message" },
15631   { 0xD7, "Send Text of Multi-block Message" },
15632   { 0xD8, "SMBreadbulk" },
15633   { 0xD9, "SMBwritebulk" },
15634   { 0xDA, "SMBwritebulkdata" },
15635   { 0xDB, "unknown-0xDB" },
15636   { 0xDC, "unknown-0xDC" },
15637   { 0xDD, "unknown-0xDD" },
15638   { 0xDE, "unknown-0xDE" },
15639   { 0xDF, "unknown-0xDF" },
15640   { 0xE0, "unknown-0xE0" },
15641   { 0xE1, "unknown-0xE1" },
15642   { 0xE2, "unknown-0xE2" },
15643   { 0xE3, "unknown-0xE3" },
15644   { 0xE4, "unknown-0xE4" },
15645   { 0xE5, "unknown-0xE5" },
15646   { 0xE6, "unknown-0xE6" },
15647   { 0xE7, "unknown-0xE7" },
15648   { 0xE8, "unknown-0xE8" },
15649   { 0xE9, "unknown-0xE9" },
15650   { 0xEA, "unknown-0xEA" },
15651   { 0xEB, "unknown-0xEB" },
15652   { 0xEC, "unknown-0xEC" },
15653   { 0xED, "unknown-0xED" },
15654   { 0xEE, "unknown-0xEE" },
15655   { 0xEF, "unknown-0xEF" },
15656   { 0xF0, "unknown-0xF0" },
15657   { 0xF1, "unknown-0xF1" },
15658   { 0xF2, "unknown-0xF2" },
15659   { 0xF3, "unknown-0xF3" },
15660   { 0xF4, "unknown-0xF4" },
15661   { 0xF5, "unknown-0xF5" },
15662   { 0xF6, "unknown-0xF6" },
15663   { 0xF7, "unknown-0xF7" },
15664   { 0xF8, "unknown-0xF8" },
15665   { 0xF9, "unknown-0xF9" },
15666   { 0xFA, "unknown-0xFA" },
15667   { 0xFB, "unknown-0xFB" },
15668   { 0xFC, "unknown-0xFC" },
15669   { 0xFD, "unknown-0xFD" },
15670   { 0xFE, "SMBinvalid" },
15671   { 0xFF, "unknown-0xFF" },
15672   { 0x00, NULL },
15673 };
15674
15675 static const char *decode_smb_name(guint8 cmd)
15676 {
15677   return(smb_cmd_vals[cmd].strptr);
15678 }
15679
15680
15681
15682 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15683  * Everything TVBUFFIFIED above this line
15684  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15685
15686
15687 static void
15688 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
15689 {
15690         conv_tables_t *ct = ctarg;
15691
15692         if (ct->unmatched)
15693                 g_hash_table_destroy(ct->unmatched);
15694         if (ct->matched)
15695                 g_hash_table_destroy(ct->matched);
15696         if (ct->tid_service)
15697                 g_hash_table_destroy(ct->tid_service);
15698 }
15699
15700 static void
15701 smb_init_protocol(void)
15702 {
15703         /*
15704          * Free the hash tables attached to the conversation table
15705          * structures, and then free the list of conversation table
15706          * data structures (which doesn't free the data structures
15707          * themselves; that's done by destroying the chunk from
15708          * which they were allocated).
15709          */
15710         if (conv_tables) {
15711                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15712                 g_slist_free(conv_tables);
15713                 conv_tables = NULL;
15714         }
15715 }
15716
15717 static const value_string errcls_types[] = {
15718   { SMB_SUCCESS, "Success"},
15719   { SMB_ERRDOS, "DOS Error"},
15720   { SMB_ERRSRV, "Server Error"},
15721   { SMB_ERRHRD, "Hardware Error"},
15722   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15723   { 0, NULL }
15724 };
15725
15726 /* Error codes for the ERRSRV class */
15727
15728 static const value_string SRV_errors[] = {
15729   {SMBE_error, "Non specific error code"},
15730   {SMBE_badpw, "Bad password"},
15731   {SMBE_badtype, "Reserved"},
15732   {SMBE_access, "No permissions to perform the requested operation"},
15733   {SMBE_invnid, "TID invalid"},
15734   {SMBE_invnetname, "Invalid network name. Service not found"},
15735   {SMBE_invdevice, "Invalid device"},
15736   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15737   {SMBE_qfull, "Print queue full"},
15738   {SMBE_qtoobig, "Queued item too big"},
15739   {SMBE_qeof, "EOF on print queue dump"},
15740   {SMBE_invpfid, "Invalid print file in smb_fid"},
15741   {SMBE_smbcmd, "Unrecognised command"},
15742   {SMBE_srverror, "SMB server internal error"},
15743   {SMBE_filespecs, "Fid and pathname invalid combination"},
15744   {SMBE_badlink, "Bad link in request ???"},
15745   {SMBE_badpermits, "Access specified for a file is not valid"},
15746   {SMBE_badpid, "Bad process id in request"},
15747   {SMBE_setattrmode, "Attribute mode invalid"},
15748   {SMBE_paused, "Message server paused"},
15749   {SMBE_msgoff, "Not receiving messages"},
15750   {SMBE_noroom, "No room for message"},
15751   {SMBE_rmuns, "Too many remote usernames"},
15752   {SMBE_timeout, "Operation timed out"},
15753   {SMBE_noresource, "No resources currently available for request."},
15754   {SMBE_toomanyuids, "Too many userids"},
15755   {SMBE_baduid, "Bad userid"},
15756   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15757   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15758   {SMBE_contMPX, "Resume MPX mode"},
15759   {SMBE_badPW, "Bad Password???"},
15760   {SMBE_nosupport, "Operation not supported"},
15761   { 0, NULL}
15762 };
15763
15764 /* Error codes for the ERRHRD class */
15765
15766 static const value_string HRD_errors[] = {
15767   {SMBE_nowrite, "Read only media"},
15768   {SMBE_badunit, "Unknown device"},
15769   {SMBE_notready, "Drive not ready"},
15770   {SMBE_badcmd, "Unknown command"},
15771   {SMBE_data, "Data (CRC) error"},
15772   {SMBE_badreq, "Bad request structure length"},
15773   {SMBE_seek, "Seek error"},
15774   {SMBE_badmedia, "Unknown media type"},
15775   {SMBE_badsector, "Sector not found"},
15776   {SMBE_nopaper, "Printer out of paper"},
15777   {SMBE_write, "Write fault"},
15778   {SMBE_read, "Read fault"},
15779   {SMBE_general, "General failure"},
15780   {SMBE_badshare, "A open conflicts with an existing open"},
15781   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15782   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15783   {SMBE_FCBunavail, "No FCBs are available to process request"},
15784   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15785   {SMBE_diskfull, "Disk full???"},
15786   {0, NULL}
15787 };
15788
15789 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
15790 {
15791
15792   switch (errcls) {
15793
15794   case SMB_SUCCESS:
15795
15796     return("No Error");   /* No error ??? */
15797     break;
15798
15799   case SMB_ERRDOS:
15800
15801     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15802     break;
15803
15804   case SMB_ERRSRV:
15805
15806     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15807     break;
15808
15809   case SMB_ERRHRD:
15810
15811     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15812     break;
15813
15814   default:
15815
15816     return("Unknown error class!");
15817
15818   }
15819
15820 }
15821
15822 static const true_false_string tfs_smb_flags_lock = {
15823         "Lock&Read, Write&Unlock are supported",
15824         "Lock&Read, Write&Unlock are not supported"
15825 };
15826 static const true_false_string tfs_smb_flags_receive_buffer = {
15827         "Receive buffer has been posted",
15828         "Receive buffer has not been posted"
15829 };
15830 static const true_false_string tfs_smb_flags_caseless = {
15831         "Path names are caseless",
15832         "Path names are case sensitive"
15833 };
15834 static const true_false_string tfs_smb_flags_canon = {
15835         "Pathnames are canonicalized",
15836         "Pathnames are not canonicalized"
15837 };
15838 static const true_false_string tfs_smb_flags_oplock = {
15839         "OpLock requested/granted",
15840         "OpLock not requested/granted"
15841 };
15842 static const true_false_string tfs_smb_flags_notify = {
15843         "Notify client on all modifications",
15844         "Notify client only on open"
15845 };
15846 static const true_false_string tfs_smb_flags_response = {
15847         "Message is a response to the client/redirector",
15848         "Message is a request to the server"
15849 };
15850
15851 static int
15852 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15853 {
15854         guint8 mask;
15855         proto_item *item = NULL;
15856         proto_tree *tree = NULL;
15857
15858         mask = tvb_get_guint8(tvb, offset);
15859
15860         if(parent_tree){
15861                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15862                         "Flags: 0x%02x", mask);
15863                 tree = proto_item_add_subtree(item, ett_smb_flags);
15864         }
15865         proto_tree_add_boolean(tree, hf_smb_flags_response,
15866                 tvb, offset, 1, mask);
15867         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15868                 tvb, offset, 1, mask);
15869         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15870                 tvb, offset, 1, mask);
15871         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15872                 tvb, offset, 1, mask);
15873         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15874                 tvb, offset, 1, mask);
15875         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15876                 tvb, offset, 1, mask);
15877         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15878                 tvb, offset, 1, mask);
15879         offset += 1;
15880         return offset;
15881 }
15882
15883
15884
15885 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15886         "Long file names are allowed in the response",
15887         "Long file names are not allowed in the response"
15888 };
15889 static const true_false_string tfs_smb_flags2_ea = {
15890         "Extended attributes are supported",
15891         "Extended attributes are not supported"
15892 };
15893 static const true_false_string tfs_smb_flags2_sec_sig = {
15894         "Security signatures are supported",
15895         "Security signatures are not supported"
15896 };
15897 static const true_false_string tfs_smb_flags2_long_names_used = {
15898         "Path names in request are long file names",
15899         "Path names in request are not long file names"
15900 };
15901 static const true_false_string tfs_smb_flags2_esn = {
15902         "Extended security negotiation is supported",
15903         "Extended security negotiation is not supported"
15904 };
15905 static const true_false_string tfs_smb_flags2_dfs = {
15906         "Resolve pathnames with Dfs",
15907         "Don't resolve pathnames with Dfs"
15908 };
15909 static const true_false_string tfs_smb_flags2_roe = {
15910         "Permit reads if execute-only",
15911         "Don't permit reads if execute-only"
15912 };
15913 static const true_false_string tfs_smb_flags2_nt_error = {
15914         "Error codes are NT error codes",
15915         "Error codes are DOS error codes"
15916 };
15917 static const true_false_string tfs_smb_flags2_string = {
15918         "Strings are Unicode",
15919         "Strings are ASCII"
15920 };
15921 static int
15922 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15923 {
15924         guint16 mask;
15925         proto_item *item = NULL;
15926         proto_tree *tree = NULL;
15927
15928         mask = tvb_get_letohs(tvb, offset);
15929
15930         if(parent_tree){
15931                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15932                         "Flags2: 0x%04x", mask);
15933                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15934         }
15935
15936         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15937                 tvb, offset, 2, mask);
15938         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15939                 tvb, offset, 2, mask);
15940         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15941                 tvb, offset, 2, mask);
15942         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15943                 tvb, offset, 2, mask);
15944         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15945                 tvb, offset, 2, mask);
15946         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15947                 tvb, offset, 2, mask);
15948         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15949                 tvb, offset, 2, mask);
15950         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15951                 tvb, offset, 2, mask);
15952         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15953                 tvb, offset, 2, mask);
15954
15955         offset += 2;
15956         return offset;
15957 }
15958
15959
15960
15961 #define SMB_FLAGS_DIRN 0x80
15962
15963
15964 static void
15965 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15966 {
15967         int offset = 0;
15968         proto_item *item = NULL, *hitem = NULL;
15969         proto_tree *tree = NULL, *htree = NULL;
15970         proto_item *tmp_item=NULL;
15971         guint8          flags;
15972         guint16         flags2;
15973         smb_info_t              *si;
15974         smb_saved_info_t *sip = NULL;
15975         smb_saved_info_key_t key;
15976         smb_saved_info_key_t *new_key;
15977         guint8 errclass = 0;
15978         guint16 errcode = 0;
15979         guint32 pid_mid;
15980         conversation_t *conversation;
15981         nstime_t t, deltat;
15982
15983         si=ep_alloc(sizeof(smb_info_t));
15984
15985         top_tree=parent_tree;
15986
15987         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15988                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15989         }
15990         if (check_col(pinfo->cinfo, COL_INFO)){
15991                 col_clear(pinfo->cinfo, COL_INFO);
15992         }
15993
15994         /* start off using the local variable, we will allocate a new one if we
15995            need to*/
15996         si->cmd = tvb_get_guint8(tvb, offset+4);
15997         flags = tvb_get_guint8(tvb, offset+9);
15998         /*
15999          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16000          * the direction flag appears never to be set, even for what appear
16001          * to be replies.  Do some SMB servers fail to set that flag,
16002          * under the assumption that the client knows it's a reply because
16003          * it received it?
16004          */
16005         si->request = !(flags&SMB_FLAGS_DIRN);
16006         flags2 = tvb_get_letohs(tvb, offset+10);
16007         if(flags2 & 0x8000){
16008                 si->unicode = TRUE; /* Mark them as Unicode */
16009         } else {
16010                 si->unicode = FALSE;
16011         }
16012         si->tid = tvb_get_letohs(tvb, offset+24);
16013         si->pid = tvb_get_letohs(tvb, offset+26);
16014         si->uid = tvb_get_letohs(tvb, offset+28);
16015         si->mid = tvb_get_letohs(tvb, offset+30);
16016         pid_mid = (si->pid << 16) | si->mid;
16017         si->info_level = -1;
16018         si->info_count = -1;
16019
16020         if (parent_tree) {
16021                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16022                         -1, FALSE);
16023                 tree = proto_item_add_subtree(item, ett_smb);
16024
16025                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16026                         "SMB Header");
16027
16028                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16029         }
16030
16031         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16032         offset += 4;  /* Skip the marker */
16033
16034         /* find which conversation we are part of and get the tables for that
16035            conversation*/
16036         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16037                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16038         if(!conversation){
16039                 /* OK this is a new conversation so lets create it */
16040                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16041                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16042         }
16043         /* see if we already have the smb data for this conversation */
16044         si->ct=conversation_get_proto_data(conversation, proto_smb);
16045         if(!si->ct){
16046                 /* No, not yet. create it and attach it to the conversation */
16047                 si->ct = se_alloc(sizeof(conv_tables_t));
16048
16049                         conv_tables = g_slist_prepend(conv_tables, si->ct);
16050                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16051                         smb_saved_info_equal_matched);
16052                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16053                         smb_saved_info_equal_unmatched);
16054                 si->ct->tid_service=g_hash_table_new(
16055                         smb_saved_info_hash_unmatched,
16056                         smb_saved_info_equal_unmatched);
16057                 si->ct->raw_ntlmssp = 0;
16058                 
16059                 si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
16060                 si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
16061                 si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
16062                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16063         }
16064
16065         if( (si->request)
16066             &&  (si->mid==0)
16067             &&  (si->uid==0)
16068             &&  (si->pid==0)
16069             &&  (si->tid==0) ){
16070                 /* this is a broadcast SMB packet, there will not be a reply.
16071                    We dont need to do anything
16072                 */
16073                 si->unidir = TRUE;
16074         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16075                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16076                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16077                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16078                 /* Ok, we got a special request type. This request is either
16079                    an NT Cancel or a continuation relative to a real request
16080                    in an earlier packet.  In either case, we don't expect any
16081                    responses to this packet.  For continuations, any later
16082                    responses we see really just belong to the original request.
16083                    Anyway, we want to remember this packet somehow and
16084                    remember which original request it is associated with so
16085                    we can say nice things such as "This is a Cancellation to
16086                    the request in frame x", but we don't want the
16087                    request/response matching to get messed up.
16088
16089                    The only thing we do in this case is trying to find which original
16090                    request we match with and insert an entry for this "special"
16091                    request for later reference. We continue to reference the original
16092                    requests smb_saved_info_t but we dont touch it or change anything
16093                    in it.
16094                 */
16095
16096                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16097
16098                 if(!pinfo->fd->flags.visited){
16099                         /* try to find which original call we match and if we
16100                            find it add us to the matched table. Dont touch
16101                            anything else since we dont want this one to mess
16102                            up the request/response matching. We still consider
16103                            the initial call the real request and this is only
16104                            some sort of continuation.
16105                         */
16106                         /* we only check the unmatched table and assume that the
16107                            last seen MID matching ours is the right one.
16108                            This can fail but is better than nothing
16109                         */
16110                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16111                         if(sip!=NULL){
16112                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16113                                 new_key->frame = pinfo->fd->num;
16114                                 new_key->pid_mid = pid_mid;
16115                                 g_hash_table_insert(si->ct->matched, new_key,
16116                                     sip);
16117                         }
16118                 } else {
16119                         /* we have seen this packet before; check the
16120                            matching table
16121                         */
16122                         key.frame = pinfo->fd->num;
16123                         key.pid_mid = pid_mid;
16124                         sip=g_hash_table_lookup(si->ct->matched, &key);
16125                         if(sip==NULL){
16126                         /*
16127                           We didn't find it.
16128                           Too bad, unfortunately there is not really much we can
16129                           do now since this means that we never saw the initial
16130                           request.
16131                          */
16132                         }
16133                 }
16134
16135
16136                 if(sip && sip->frame_req){
16137                         switch(si->cmd){
16138                         case SMB_COM_NT_CANCEL:
16139                                 tmp_item=proto_tree_add_uint(htree, hf_smb_cancel_to,
16140                                                     tvb, 0, 0, sip->frame_req);
16141                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16142                                 break;
16143                         case SMB_COM_TRANSACTION_SECONDARY:
16144                         case SMB_COM_TRANSACTION2_SECONDARY:
16145                         case SMB_COM_NT_TRANSACT_SECONDARY:
16146                                 tmp_item=proto_tree_add_uint(htree, hf_smb_continuation_to,
16147                                                     tvb, 0, 0, sip->frame_req);
16148                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16149                                 break;
16150                         }
16151                 } else {
16152                         switch(si->cmd){
16153                         case SMB_COM_NT_CANCEL:
16154                                 proto_tree_add_text(htree, tvb, 0, 0,
16155                                                     "Cancellation to: <unknown frame>");
16156                                 break;
16157                         case SMB_COM_TRANSACTION_SECONDARY:
16158                         case SMB_COM_TRANSACTION2_SECONDARY:
16159                         case SMB_COM_NT_TRANSACT_SECONDARY:
16160                                 proto_tree_add_text(htree, tvb, 0, 0,
16161                                                     "Continuation to: <unknown frame>");
16162                                 break;
16163                         }
16164                 }
16165         } else { /* normal bidirectional request or response */
16166                 si->unidir = FALSE;
16167
16168                 if(!pinfo->fd->flags.visited){
16169                         /* first see if we find an unmatched smb "equal" to
16170                            the current one
16171                         */
16172                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16173                         if(sip!=NULL){
16174                                 gboolean cmd_match=FALSE;
16175
16176                                 /*
16177                                  * Make sure the SMB we found was the
16178                                  * same command, or a different command
16179                                  * that's another valid type of reply
16180                                  * to that command.
16181                                  */
16182                                 if(si->cmd==sip->cmd){
16183                                         cmd_match=TRUE;
16184                                 }
16185                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16186                                         cmd_match=TRUE;
16187                                 }
16188                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16189                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16190                                         cmd_match=TRUE;
16191                                 }
16192                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16193                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16194                                         cmd_match=TRUE;
16195                                 }
16196                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16197                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16198                                         cmd_match=TRUE;
16199                                 }
16200
16201                                 if( (si->request) || (!cmd_match) ) {
16202                                         /* We are processing an SMB request but there was already
16203                                            another "identical" smb request we had not matched yet.
16204                                            This must mean that either we have a retransmission or that the
16205                                            response to the previous one was lost and the client has reused
16206                                            the MID for this conversation. In either case it's not much more
16207                                            we can do than forget the old request and concentrate on the
16208                                            present one instead.
16209
16210                                            We also do this cleanup if we see that the cmd in the original
16211                                            request in sip->cmd is not compatible with the current cmd.
16212                                            This is to prevent matching errors such as if there were two
16213                                            SMBs of different cmds but with identical MID and PID values and
16214                                            if wireshark lost the first reply and the second request.
16215                                         */
16216                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16217                                         sip=NULL; /* XXX should free it as well */
16218                                 } else {
16219                                         /* we have found a response to some
16220                                            request we have seen earlier.
16221                                            What we do now depends on whether
16222                                            this is the first response to that
16223                                            request we see (id frame_res==0) or
16224                                            if it's a response to a request
16225                                            for which we've seen an earlier
16226                                            response that's continued.
16227                                         */
16228                                         if(sip->frame_res==0 ||
16229                                            sip->flags & SMB_SIF_IS_CONTINUED){
16230                                                 /* OK, it is the first response
16231                                                    we have seen to this packet,
16232                                                    or it's a continuation of
16233                                                    a response we've seen. */
16234                                                 sip->frame_res = pinfo->fd->num;
16235                                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16236                                                 new_key->frame = sip->frame_res;
16237                                                 new_key->pid_mid = pid_mid;
16238                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16239                                                 /* We remove the entry for unmatched since we have found a match.
16240                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
16241                                                  * and if there is packetloss in the trace (maybe due to large holes
16242                                                  * created by a sniffer device not being able to keep up
16243                                                  * with the line rate.
16244                                                  * There is a real possibility that the following would occur which is painful :
16245                                                  * 1, -> Request  MID:5
16246                                                  * 2, <- Response MID:5
16247                                                  *   3, ->Request  MID:5 (missing from capture)
16248                                                  * 4, <- Response MID:5
16249                                                  * We DONT want #4 to be presented as a response to #1
16250                                                  */
16251                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16252                                         } else {
16253                                                 /* We have already seen another response to this MID.
16254                                                    Since the MID in reality is only something like 10 bits
16255                                                    this probably means that we just have a MID that is being
16256                                                    reused due to the small MID space and that this is a new
16257                                                    command we did not see the original request for.
16258                                                 */
16259                                                 sip=NULL;
16260                                         }
16261                                 }
16262                         }
16263                         if(si->request){
16264                                 sip = se_alloc(sizeof(smb_saved_info_t));
16265                                 sip->frame_req = pinfo->fd->num;
16266                                 sip->frame_res = 0;
16267                                 sip->req_time = pinfo->fd->abs_ts;
16268                                 sip->flags = 0;
16269                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
16270                                     == (void *)TID_IPC) {
16271                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16272                                 }
16273                                 sip->cmd = si->cmd;
16274                                 sip->extra_info = NULL;
16275                                 sip->extra_info_type = SMB_EI_NONE;
16276                                 sip->fid=0;
16277                                 sip->fid_seen_in_request=0;
16278                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
16279                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16280                                 new_key->frame = sip->frame_req;
16281                                 new_key->pid_mid = pid_mid;
16282                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16283                         }
16284                 } else {
16285                         /* we have seen this packet before; check the
16286                            matching table.
16287                            If we haven't yet seen the reply, we won't
16288                            find the info for it; we don't need it, as
16289                            we only use it to save information, and, as
16290                            we've seen this packet before, we've already
16291                            saved the information.
16292                         */
16293                         key.frame = pinfo->fd->num;
16294                         key.pid_mid = pid_mid;
16295                         sip=g_hash_table_lookup(si->ct->matched, &key);
16296                 }
16297         }
16298
16299         /*
16300          * Pass the "sip" on to subdissectors through "si".
16301          */
16302         si->sip = sip;
16303
16304         if (sip != NULL) {
16305                 /*
16306                  * Put in fields for the frame number of the frame to which
16307                  * this is a response or the frame with the response to this
16308                  * frame - if we know the frame number (i.e., it's not 0).
16309                  */
16310                 if(si->request){
16311                         if (sip->frame_res != 0) {
16312                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16313                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16314                         }
16315                 } else {
16316                         if (sip->frame_req != 0) {
16317                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16318                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16319                                 t = pinfo->fd->abs_ts;
16320                                 nstime_delta(&deltat, &t, &sip->req_time);
16321                                 tmp_item=proto_tree_add_time(htree, hf_smb_time, tvb,
16322                                     0, 0, &deltat);
16323                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16324                         }
16325                 }
16326         }
16327
16328         /* smb command */
16329         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);
16330         offset += 1;
16331
16332         if(flags2 & 0x4000){
16333                 /* handle NT 32 bit error code */
16334
16335                 si->nt_status = tvb_get_letohl(tvb, offset);
16336
16337                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16338                         TRUE);
16339                 offset += 4;
16340
16341         } else {
16342                 /* handle DOS error code & class */
16343                 errclass = tvb_get_guint8(tvb, offset);
16344                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16345                         errclass);
16346                 offset += 1;
16347
16348                 /* reserved byte */
16349                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16350                 offset += 1;
16351
16352                 /* error code */
16353                 /* XXX - the type of this field depends on the value of
16354                  * "errcls", so there is isn't a single value_string array
16355                  * fo it, so there can't be a single field for it.
16356                  */
16357                 errcode = tvb_get_letohs(tvb, offset);
16358                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16359                         offset, 2, errcode, "Error Code: %s",
16360                         decode_smb_error(errclass, errcode));
16361                 offset += 2;
16362         }
16363
16364         /* flags */
16365         offset = dissect_smb_flags(tvb, htree, offset);
16366
16367         /* flags2 */
16368         offset = dissect_smb_flags2(tvb, htree, offset);
16369
16370         /*
16371          * The document at
16372          *
16373          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16374          *
16375          * (a text version of "Microsoft Networks SMB FILE SHARING
16376          * PROTOCOL, Document Version 6.0p") says that:
16377          *
16378          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16379          *      the "High Part of PID";
16380          *
16381          *      the next four bytes are reserved;
16382          *
16383          *      the next four bytes are, for SMB-over-IPX (with no
16384          *      NetBIOS involved) two bytes of Session ID and two bytes
16385          *      of SequenceNumber.
16386          *
16387          * Network Monitor 2.x dissects the four bytes before the Session ID
16388          * as a "Key", and the two bytes after the SequenceNumber as
16389          * a "Group ID".
16390          *
16391          * The "High Part of PID" has been seen in calls other than NT
16392          * Create and X, although most of them appear to be I/O on DCE RPC
16393          * pipes opened with the NT Create and X in question.
16394          */
16395         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16396         offset += 2;
16397
16398         if (pinfo->ptype == PT_IPX &&
16399             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16400              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16401              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16402                 /*
16403                  * This is SMB-over-IPX.
16404                  * XXX - do we have to worry about "sequenced commands",
16405                  * as per the Samba document?  They say that for
16406                  * "unsequenced commands" (with a sequence number of 0),
16407                  * the Mid must be unique, but perhaps the Mid doesn't
16408                  * have to be unique for sequenced commands.  In at least
16409                  * one capture with SMB-over-IPX, however, the Mids
16410                  * are unique even for sequenced commands.
16411                  */
16412                 /* Key */
16413                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16414                     TRUE);
16415                 offset += 4;
16416
16417                 /* Session ID */
16418                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16419                     TRUE);
16420                 offset += 2;
16421
16422                 /* Sequence number */
16423                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16424                     TRUE);
16425                 offset += 2;
16426
16427                 /* Group ID */
16428                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16429                     TRUE);
16430                 offset += 2;
16431         } else {
16432                 /*
16433                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16434                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16435                  * bytes after the "High part of PID" are an 8-byte
16436                  * signature ...
16437                  */
16438                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16439                 offset += 8;
16440
16441                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16442                 offset += 2;
16443         }
16444
16445         pinfo->private_data = si;
16446
16447         /* TID
16448          * TreeConnectAndX(0x75) is special, here it is the mere fact of 
16449          * having a response that means that the share was mapped and we 
16450          * need to track it
16451          */
16452         if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
16453                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
16454         } else {
16455                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
16456         }
16457
16458         /* PID */
16459         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16460         offset += 2;
16461
16462         /* UID */
16463         offset=dissect_smb_uid(tvb, htree, offset, si);
16464
16465         /* MID */
16466         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16467         offset += 2;
16468
16469         /* tap the packet before the dissectors are called so we still get
16470            the tap listener called even if there is an exception.
16471         */
16472         tap_queue_packet(smb_tap, pinfo, si);
16473         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16474
16475         /* Append error info from this packet to info string. */
16476         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16477                 if (flags2 & 0x4000) {
16478                         /*
16479                          * The status is an NT status code; was there
16480                          * an error?
16481                          */
16482                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
16483                                 /*
16484                                  * Yes.
16485                                  */
16486                                 col_append_fstr(
16487                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16488                                         val_to_str(si->nt_status, NT_errors,
16489                                             "Unknown (0x%08X)"));
16490                         }
16491                 } else {
16492                         /*
16493                          * The status is a DOS error class and code; was
16494                          * there an error?
16495                          */
16496                         if (errclass != SMB_SUCCESS) {
16497                                 /*
16498                                  * Yes.
16499                                  */
16500                                 col_append_fstr(
16501                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16502                                         decode_smb_error(errclass, errcode));
16503                         }
16504                 }
16505         }
16506 }
16507
16508 static gboolean
16509 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16510 {
16511         /* must check that this really is a smb packet */
16512         if (!tvb_bytes_exist(tvb, 0, 4))
16513                 return FALSE;
16514
16515         if( (tvb_get_guint8(tvb, 0) != 0xff)
16516             || (tvb_get_guint8(tvb, 1) != 'S')
16517             || (tvb_get_guint8(tvb, 2) != 'M')
16518             || (tvb_get_guint8(tvb, 3) != 'B') ){
16519                 return FALSE;
16520         }
16521
16522         dissect_smb(tvb, pinfo, parent_tree);
16523         return TRUE;
16524 }
16525
16526 void
16527 proto_register_smb(void)
16528 {
16529         static hf_register_info hf[] = {
16530         { &hf_smb_cmd,
16531                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16532                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16533
16534         { &hf_smb_trans2_subcmd,
16535                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16536                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16537
16538         { &hf_smb_nt_trans_subcmd,
16539                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16540                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16541
16542         { &hf_smb_word_count,
16543                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16544                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16545
16546         { &hf_smb_byte_count,
16547                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16548                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16549
16550         { &hf_smb_response_to,
16551                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16552                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16553
16554         { &hf_smb_time,
16555                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16556                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16557
16558         { &hf_smb_response_in,
16559                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16560                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16561
16562         { &hf_smb_continuation_to,
16563                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16564                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16565
16566         { &hf_smb_nt_status,
16567                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16568                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16569
16570         { &hf_smb_error_class,
16571                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16572                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16573
16574         { &hf_smb_error_code,
16575                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16576                 NULL, 0, "DOS Error Code", HFILL }},
16577
16578         { &hf_smb_reserved,
16579                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16580                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16581
16582         { &hf_smb_sig,
16583                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16584                 NULL, 0, "Signature bytes", HFILL }},
16585
16586         { &hf_smb_key,
16587                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16588                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16589
16590         { &hf_smb_session_id,
16591                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16592                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16593
16594         { &hf_smb_sequence_num,
16595                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16596                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16597
16598         { &hf_smb_group_id,
16599                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16600                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16601
16602         { &hf_smb_pid,
16603                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16604                 NULL, 0, "Process ID", HFILL }},
16605
16606         { &hf_smb_pid_high,
16607                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16608                 NULL, 0, "Process ID High Bytes", HFILL }},
16609
16610         { &hf_smb_tid,
16611                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16612                 NULL, 0, "Tree ID", HFILL }},
16613
16614         { &hf_smb_uid,
16615                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16616                 NULL, 0, "User ID", HFILL }},
16617
16618         { &hf_smb_mid,
16619                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16620                 NULL, 0, "Multiplex ID", HFILL }},
16621
16622         { &hf_smb_flags_lock,
16623                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16624                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16625
16626         { &hf_smb_flags_receive_buffer,
16627                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16628                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16629
16630         { &hf_smb_flags_caseless,
16631                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16632                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16633
16634         { &hf_smb_flags_canon,
16635                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16636                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16637
16638         { &hf_smb_flags_oplock,
16639                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16640                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16641
16642         { &hf_smb_flags_notify,
16643                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16644                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16645
16646         { &hf_smb_flags_response,
16647                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16648                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16649
16650         { &hf_smb_flags2_long_names_allowed,
16651                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16652                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16653
16654         { &hf_smb_flags2_ea,
16655                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16656                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16657
16658         { &hf_smb_flags2_sec_sig,
16659                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16660                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16661
16662         { &hf_smb_flags2_long_names_used,
16663                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16664                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16665
16666         { &hf_smb_flags2_esn,
16667                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16668                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16669
16670         { &hf_smb_flags2_dfs,
16671                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16672                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16673
16674         { &hf_smb_flags2_roe,
16675                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16676                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16677
16678         { &hf_smb_flags2_nt_error,
16679                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16680                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16681
16682         { &hf_smb_flags2_string,
16683                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16684                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16685
16686         { &hf_smb_buffer_format,
16687                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16688                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16689
16690         { &hf_smb_dialect_name,
16691                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16692                 NULL, 0, "Name of dialect", HFILL }},
16693
16694         { &hf_smb_dialect_index,
16695                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16696                 NULL, 0, "Index of selected dialect", HFILL }},
16697
16698         { &hf_smb_max_trans_buf_size,
16699                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16700                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16701
16702         { &hf_smb_max_mpx_count,
16703                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16704                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16705
16706         { &hf_smb_max_vcs_num,
16707                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16708                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16709
16710         { &hf_smb_session_key,
16711                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16712                 NULL, 0, "Unique token identifying this session", HFILL }},
16713
16714         { &hf_smb_server_timezone,
16715                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16716                 NULL, 0, "Current timezone at server.", HFILL }},
16717
16718         { &hf_smb_encryption_key_length,
16719                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16720                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16721
16722         { &hf_smb_encryption_key,
16723                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16724                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16725
16726         { &hf_smb_primary_domain,
16727                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16728                 NULL, 0, "The server's primary domain", HFILL }},
16729
16730         { &hf_smb_server,
16731                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16732                 NULL, 0, "The name of the DC/server", HFILL }},
16733
16734         { &hf_smb_max_raw_buf_size,
16735                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16736                 NULL, 0, "Maximum raw buffer size", HFILL }},
16737
16738         { &hf_smb_server_guid,
16739                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16740                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16741
16742         { &hf_smb_security_blob_len,
16743                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16744                 NULL, 0, "Security blob length", HFILL }},
16745
16746         { &hf_smb_security_blob,
16747                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16748                 NULL, 0, "Security blob", HFILL }},
16749
16750         { &hf_smb_sm_mode16,
16751                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16752                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16753
16754         { &hf_smb_sm_password16,
16755                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16756                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16757
16758         { &hf_smb_sm_mode,
16759                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16760                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16761
16762         { &hf_smb_sm_password,
16763                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16764                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16765
16766         { &hf_smb_sm_signatures,
16767                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16768                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16769
16770         { &hf_smb_sm_sig_required,
16771                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16772                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16773
16774         { &hf_smb_rm_read,
16775                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16776                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16777
16778         { &hf_smb_rm_write,
16779                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16780                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16781
16782         { &hf_smb_server_date_time,
16783                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16784                 NULL, 0, "Current date and time at server", HFILL }},
16785
16786         { &hf_smb_server_smb_date,
16787                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16788                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16789
16790         { &hf_smb_server_smb_time,
16791                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16792                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16793
16794         { &hf_smb_server_cap_raw_mode,
16795                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16796                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16797
16798         { &hf_smb_server_cap_mpx_mode,
16799                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16800                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16801
16802         { &hf_smb_server_cap_unicode,
16803                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16804                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16805
16806         { &hf_smb_server_cap_large_files,
16807                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16808                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16809
16810         { &hf_smb_server_cap_nt_smbs,
16811                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16812                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16813
16814         { &hf_smb_server_cap_rpc_remote_apis,
16815                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16816                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16817
16818         { &hf_smb_server_cap_nt_status,
16819                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16820                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16821
16822         { &hf_smb_server_cap_level_ii_oplocks,
16823                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16824                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16825
16826         { &hf_smb_server_cap_lock_and_read,
16827                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16828                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16829
16830         { &hf_smb_server_cap_nt_find,
16831                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16832                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16833
16834         { &hf_smb_server_cap_dfs,
16835                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16836                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16837
16838         { &hf_smb_server_cap_infolevel_passthru,
16839                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16840                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16841
16842         { &hf_smb_server_cap_large_readx,
16843                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16844                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16845
16846         { &hf_smb_server_cap_large_writex,
16847                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16848                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16849
16850         { &hf_smb_server_cap_unix,
16851                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16852                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16853
16854         { &hf_smb_server_cap_reserved,
16855                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16856                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16857
16858         { &hf_smb_server_cap_bulk_transfer,
16859                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16860                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16861
16862         { &hf_smb_server_cap_compressed_data,
16863                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16864                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16865
16866         { &hf_smb_server_cap_extended_security,
16867                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16868                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16869
16870         { &hf_smb_system_time,
16871                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16872                 NULL, 0, "System Time", HFILL }},
16873
16874         { &hf_smb_unknown,
16875                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16876                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16877
16878         { &hf_smb_dir_name,
16879                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16880                 NULL, 0, "SMB Directory Name", HFILL }},
16881
16882         { &hf_smb_echo_count,
16883                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16884                 NULL, 0, "Number of times to echo data back", HFILL }},
16885
16886         { &hf_smb_echo_data,
16887                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16888                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16889
16890         { &hf_smb_echo_seq_num,
16891                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16892                 NULL, 0, "Sequence number for this echo response", HFILL }},
16893
16894         { &hf_smb_max_buf_size,
16895                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16896                 NULL, 0, "Max client buffer size", HFILL }},
16897
16898         { &hf_smb_path,
16899                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16900                 NULL, 0, "Path. Server name and share name", HFILL }},
16901
16902         { &hf_smb_service,
16903                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16904                 NULL, 0, "Service name", HFILL }},
16905
16906         { &hf_smb_password,
16907                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16908                 NULL, 0, "Password", HFILL }},
16909
16910         { &hf_smb_ansi_password,
16911                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16912                 NULL, 0, "ANSI Password", HFILL }},
16913
16914         { &hf_smb_unicode_password,
16915                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16916                 NULL, 0, "Unicode Password", HFILL }},
16917
16918         { &hf_smb_move_flags_file,
16919                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16920                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16921
16922         { &hf_smb_move_flags_dir,
16923                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16924                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16925
16926         { &hf_smb_move_flags_verify,
16927                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16928                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16929
16930         { &hf_smb_files_moved,
16931                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16932                 NULL, 0, "Number of files moved", HFILL }},
16933
16934         { &hf_smb_copy_flags_file,
16935                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16936                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16937
16938         { &hf_smb_copy_flags_dir,
16939                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16940                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16941
16942         { &hf_smb_copy_flags_dest_mode,
16943                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16944                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16945
16946         { &hf_smb_copy_flags_source_mode,
16947                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16948                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16949
16950         { &hf_smb_copy_flags_verify,
16951                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16952                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16953
16954         { &hf_smb_copy_flags_tree_copy,
16955                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16956                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16957
16958         { &hf_smb_copy_flags_ea_action,
16959                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16960                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16961
16962         { &hf_smb_count,
16963                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16964                 NULL, 0, "Count number of items/bytes", HFILL }},
16965
16966         { &hf_smb_count_low,
16967                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
16968                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
16969
16970         { &hf_smb_count_high,
16971                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
16972                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
16973
16974         { &hf_smb_file_name,
16975                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16976                 NULL, 0, "File Name", HFILL }},
16977
16978         { &hf_smb_open_function_create,
16979                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16980                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16981
16982         { &hf_smb_open_function_open,
16983                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16984                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16985
16986         { &hf_smb_fid,
16987                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16988                 NULL, 0, "FID: File ID", HFILL }},
16989
16990         { &hf_smb_file_attr_read_only_16bit,
16991                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16992                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16993
16994         { &hf_smb_file_attr_read_only_8bit,
16995                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16996                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16997
16998         { &hf_smb_file_attr_hidden_16bit,
16999                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17000                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17001
17002         { &hf_smb_file_attr_hidden_8bit,
17003                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17004                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17005
17006         { &hf_smb_file_attr_system_16bit,
17007                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17008                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17009
17010         { &hf_smb_file_attr_system_8bit,
17011                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17012                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17013
17014         { &hf_smb_file_attr_volume_16bit,
17015                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17016                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17017
17018         { &hf_smb_file_attr_volume_8bit,
17019                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17020                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17021
17022         { &hf_smb_file_attr_directory_16bit,
17023                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17024                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17025
17026         { &hf_smb_file_attr_directory_8bit,
17027                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17028                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17029
17030         { &hf_smb_file_attr_archive_16bit,
17031                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17032                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17033
17034         { &hf_smb_file_attr_archive_8bit,
17035                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17036                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17037
17038         { &hf_smb_file_attr_device,
17039                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17040                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17041
17042         { &hf_smb_file_attr_normal,
17043                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17044                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17045
17046         { &hf_smb_file_attr_temporary,
17047                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17048                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17049
17050         { &hf_smb_file_attr_sparse,
17051                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17052                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17053
17054         { &hf_smb_file_attr_reparse,
17055                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17056                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17057
17058         { &hf_smb_file_attr_compressed,
17059                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17060                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17061
17062         { &hf_smb_file_attr_offline,
17063                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17064                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17065
17066         { &hf_smb_file_attr_not_content_indexed,
17067                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17068                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17069
17070         { &hf_smb_file_attr_encrypted,
17071                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17072                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17073
17074         { &hf_smb_file_size,
17075                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17076                 NULL, 0, "File Size", HFILL }},
17077
17078         { &hf_smb_search_attribute_read_only,
17079                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17080                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17081
17082         { &hf_smb_search_attribute_hidden,
17083                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17084                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17085
17086         { &hf_smb_search_attribute_system,
17087                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17088                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17089
17090         { &hf_smb_search_attribute_volume,
17091                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17092                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17093
17094         { &hf_smb_search_attribute_directory,
17095                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17096                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17097
17098         { &hf_smb_search_attribute_archive,
17099                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17100                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17101
17102         { &hf_smb_access_mode,
17103                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17104                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17105
17106         { &hf_smb_access_sharing,
17107                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17108                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17109
17110         { &hf_smb_access_locality,
17111                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17112                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17113
17114         { &hf_smb_access_caching,
17115                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17116                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17117
17118         { &hf_smb_access_writetru,
17119                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17120                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17121
17122         { &hf_smb_create_time,
17123                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17124                 NULL, 0, "Creation Time", HFILL }},
17125
17126         { &hf_smb_modify_time,
17127                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17128                   NULL, 0, "Modification Time", HFILL }},
17129
17130         { &hf_smb_backup_time,
17131                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17132                   NULL, 0, "Backup time", HFILL}},
17133
17134         { &hf_smb_mac_alloc_block_count,
17135                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17136                   NULL, 0, "Allocation Block Count", HFILL}},
17137
17138         { &hf_smb_mac_alloc_block_size,
17139                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17140                   NULL, 0, "Allocation Block Size", HFILL}},
17141
17142         { &hf_smb_mac_free_block_count,
17143                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17144                   NULL, 0, "Free Block Count", HFILL}},
17145
17146         { &hf_smb_mac_root_file_count,
17147                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17148                 NULL, 0, "Root File Count", HFILL}},
17149
17150         { &hf_smb_mac_root_dir_count,
17151           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17152             NULL, 0, "Root Directory Count", HFILL}},
17153
17154         { &hf_smb_mac_file_count,
17155           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17156             NULL, 0, "File Count", HFILL}},
17157
17158         { &hf_smb_mac_dir_count,
17159           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17160             NULL, 0, "Directory Count", HFILL}},
17161
17162         { &hf_smb_mac_support_flags,
17163           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17164             NULL, 0, "Mac Support Flags", HFILL}},
17165
17166         { &hf_smb_mac_sup_access_ctrl,
17167           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17168             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17169
17170         { &hf_smb_mac_sup_getset_comments,
17171           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17172             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17173
17174         { &hf_smb_mac_sup_desktopdb_calls,
17175           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17176             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17177
17178         { &hf_smb_mac_sup_unique_ids,
17179           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17180             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17181
17182         { &hf_smb_mac_sup_streams,
17183           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17184             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17185
17186         { &hf_smb_create_dos_date,
17187                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17188                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17189
17190         { &hf_smb_create_dos_time,
17191                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17192                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17193
17194         { &hf_smb_last_write_time,
17195                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17196                 NULL, 0, "Time this file was last written to", HFILL }},
17197
17198         { &hf_smb_last_write_dos_date,
17199                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17200                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17201
17202         { &hf_smb_last_write_dos_time,
17203                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17204                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17205
17206         { &hf_smb_old_file_name,
17207                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
17208                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17209
17210         { &hf_smb_offset,
17211                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17212                 NULL, 0, "Offset in file", HFILL }},
17213
17214         { &hf_smb_remaining,
17215                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17216                 NULL, 0, "Remaining number of bytes", HFILL }},
17217
17218         { &hf_smb_padding,
17219                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17220                 NULL, 0, "Padding or unknown data", HFILL }},
17221
17222         { &hf_smb_file_data,
17223                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17224                 NULL, 0, "Data read/written to the file", HFILL }},
17225
17226         { &hf_smb_mac_fndrinfo,
17227                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17228                   NULL, 0, "Finder Info", HFILL}},
17229
17230         { &hf_smb_total_data_len,
17231                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17232                 NULL, 0, "Total length of data", HFILL }},
17233
17234         { &hf_smb_data_len,
17235                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17236                 NULL, 0, "Length of data", HFILL }},
17237
17238         { &hf_smb_data_len_low,
17239                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17240                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17241
17242         { &hf_smb_data_len_high,
17243                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17244                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17245
17246         { &hf_smb_seek_mode,
17247                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17248                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17249
17250         { &hf_smb_access_time,
17251                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17252                 NULL, 0, "Last Access Time", HFILL }},
17253
17254         { &hf_smb_access_dos_date,
17255                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17256                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17257
17258         { &hf_smb_access_dos_time,
17259                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17260                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17261
17262         { &hf_smb_data_size,
17263                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17264                 NULL, 0, "Data Size", HFILL }},
17265
17266         { &hf_smb_alloc_size,
17267                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17268                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17269
17270         { &hf_smb_max_count,
17271                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17272                 NULL, 0, "Maximum Count", HFILL }},
17273
17274         { &hf_smb_max_count_low,
17275                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17276                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17277
17278         { &hf_smb_max_count_high,
17279                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17280                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17281
17282         { &hf_smb_min_count,
17283                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17284                 NULL, 0, "Minimum Count", HFILL }},
17285
17286         { &hf_smb_timeout,
17287                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17288                 NULL, 0, "Timeout in miliseconds", HFILL }},
17289
17290         { &hf_smb_high_offset,
17291                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17292                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17293
17294         { &hf_smb_units,
17295                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17296                 NULL, 0, "Total number of units at server", HFILL }},
17297
17298         { &hf_smb_bpu,
17299                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17300                 NULL, 0, "Blocks per unit at server", HFILL }},
17301
17302         { &hf_smb_blocksize,
17303                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17304                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17305
17306         { &hf_smb_freeunits,
17307                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17308                 NULL, 0, "Number of free units at server", HFILL }},
17309
17310         { &hf_smb_data_offset,
17311                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17312                 NULL, 0, "Data Offset", HFILL }},
17313
17314         { &hf_smb_dcm,
17315                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17316                 NULL, 0, "Data Compaction Mode", HFILL }},
17317
17318         { &hf_smb_request_mask,
17319                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17320                 NULL, 0, "Connectionless mode mask", HFILL }},
17321
17322         { &hf_smb_response_mask,
17323                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17324                 NULL, 0, "Connectionless mode mask", HFILL }},
17325
17326         { &hf_smb_search_id,
17327                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17328                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17329
17330         { &hf_smb_write_mode_write_through,
17331                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17332                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17333
17334         { &hf_smb_write_mode_return_remaining,
17335                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17336                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17337
17338         { &hf_smb_write_mode_raw,
17339                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17340                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17341
17342         { &hf_smb_write_mode_message_start,
17343                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17344                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17345
17346         { &hf_smb_write_mode_connectionless,
17347                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17348                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17349
17350         { &hf_smb_resume_key_len,
17351                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17352                 NULL, 0, "Resume Key length", HFILL }},
17353
17354         { &hf_smb_resume_find_id,
17355                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17356                 NULL, 0, "Handle for Find operation", HFILL }},
17357
17358         { &hf_smb_resume_server_cookie,
17359                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17360                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17361
17362         { &hf_smb_resume_client_cookie,
17363                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17364                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17365
17366         { &hf_smb_andxoffset,
17367                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17368                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17369
17370         { &hf_smb_lock_type_large,
17371                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17372                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17373
17374         { &hf_smb_lock_type_cancel,
17375                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17376                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17377
17378         { &hf_smb_lock_type_change,
17379                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17380                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17381
17382         { &hf_smb_lock_type_oplock,
17383                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17384                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17385
17386         { &hf_smb_lock_type_shared,
17387                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17388                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17389
17390         { &hf_smb_locking_ol,
17391                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17392                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17393
17394         { &hf_smb_number_of_locks,
17395                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17396                 NULL, 0, "Number of lock requests in this request", HFILL }},
17397
17398         { &hf_smb_number_of_unlocks,
17399                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17400                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17401
17402         { &hf_smb_lock_long_length,
17403                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17404                 NULL, 0, "Length of lock/unlock region", HFILL }},
17405
17406         { &hf_smb_lock_long_offset,
17407                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17408                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17409
17410         { &hf_smb_file_type,
17411                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17412                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17413
17414         { &hf_smb_ipc_state_nonblocking,
17415                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17416                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17417
17418         { &hf_smb_ipc_state_endpoint,
17419                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17420                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17421
17422         { &hf_smb_ipc_state_pipe_type,
17423                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17424                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17425
17426         { &hf_smb_ipc_state_read_mode,
17427                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17428                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17429
17430         { &hf_smb_ipc_state_icount,
17431                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17432                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17433
17434         { &hf_smb_server_fid,
17435                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17436                 NULL, 0, "Server unique File ID", HFILL }},
17437
17438         { &hf_smb_open_flags_add_info,
17439                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17440                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17441
17442         { &hf_smb_open_flags_ex_oplock,
17443                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17444                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17445
17446         { &hf_smb_open_flags_batch_oplock,
17447                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17448                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17449
17450         { &hf_smb_open_flags_ealen,
17451                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17452                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17453
17454         { &hf_smb_open_action_open,
17455                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17456                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17457
17458         { &hf_smb_open_action_lock,
17459                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17460                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17461
17462         { &hf_smb_vc_num,
17463                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17464                 NULL, 0, "VC Number", HFILL }},
17465
17466         { &hf_smb_password_len,
17467                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17468                 NULL, 0, "Length of password", HFILL }},
17469
17470         { &hf_smb_ansi_password_len,
17471                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17472                 NULL, 0, "Length of ANSI password", HFILL }},
17473
17474         { &hf_smb_unicode_password_len,
17475                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17476                 NULL, 0, "Length of Unicode password", HFILL }},
17477
17478         { &hf_smb_account,
17479                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17480                 NULL, 0, "Account, username", HFILL }},
17481
17482         { &hf_smb_os,
17483                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17484                 NULL, 0, "Which OS we are running", HFILL }},
17485
17486         { &hf_smb_lanman,
17487                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17488                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17489
17490         { &hf_smb_setup_action_guest,
17491                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17492                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17493
17494         { &hf_smb_fs,
17495                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17496                 NULL, 0, "Native File System", HFILL }},
17497
17498         { &hf_smb_connect_flags_dtid,
17499                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17500                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17501
17502         { &hf_smb_connect_support_search,
17503                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17504                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17505
17506         { &hf_smb_connect_support_in_dfs,
17507                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17508                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17509
17510         { &hf_smb_max_setup_count,
17511                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17512                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17513
17514         { &hf_smb_total_param_count,
17515                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17516                 NULL, 0, "Total number of parameter bytes", HFILL }},
17517
17518         { &hf_smb_total_data_count,
17519                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17520                 NULL, 0, "Total number of data bytes", HFILL }},
17521
17522         { &hf_smb_max_param_count,
17523                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17524                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17525
17526         { &hf_smb_max_data_count,
17527                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17528                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17529
17530         { &hf_smb_param_disp16,
17531                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17532                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17533
17534         { &hf_smb_param_count16,
17535                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17536                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17537
17538         { &hf_smb_param_offset16,
17539                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17540                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17541
17542         { &hf_smb_param_disp32,
17543                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17544                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17545
17546         { &hf_smb_param_count32,
17547                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17548                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17549
17550         { &hf_smb_param_offset32,
17551                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17552                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17553
17554         { &hf_smb_data_count16,
17555                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17556                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17557
17558         { &hf_smb_data_disp16,
17559                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17560                 NULL, 0, "Data Displacement", HFILL }},
17561
17562         { &hf_smb_data_offset16,
17563                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17564                 NULL, 0, "Data Offset", HFILL }},
17565
17566         { &hf_smb_data_count32,
17567                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17568                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17569
17570         { &hf_smb_data_disp32,
17571                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17572                 NULL, 0, "Data Displacement", HFILL }},
17573
17574         { &hf_smb_data_offset32,
17575                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17576                 NULL, 0, "Data Offset", HFILL }},
17577
17578         { &hf_smb_setup_count,
17579                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17580                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17581
17582         { &hf_smb_nt_ioctl_isfsctl,
17583                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17584                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17585
17586         { &hf_smb_nt_ioctl_flags_root_handle,
17587                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17588                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17589
17590         { &hf_smb_nt_notify_action,
17591                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17592                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17593
17594         { &hf_smb_nt_notify_watch_tree,
17595                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17596                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17597
17598         { &hf_smb_nt_notify_stream_write,
17599                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17600                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17601
17602         { &hf_smb_nt_notify_stream_size,
17603                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17604                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17605
17606         { &hf_smb_nt_notify_stream_name,
17607                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17608                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17609
17610         { &hf_smb_nt_notify_security,
17611                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17612                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17613
17614         { &hf_smb_nt_notify_ea,
17615                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17616                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17617
17618         { &hf_smb_nt_notify_creation,
17619                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17620                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17621
17622         { &hf_smb_nt_notify_last_access,
17623                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17624                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17625
17626         { &hf_smb_nt_notify_last_write,
17627                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17628                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17629
17630         { &hf_smb_nt_notify_size,
17631                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17632                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17633
17634         { &hf_smb_nt_notify_attributes,
17635                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17636                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17637
17638         { &hf_smb_nt_notify_dir_name,
17639                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17640                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17641
17642         { &hf_smb_nt_notify_file_name,
17643                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17644                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17645
17646         { &hf_smb_root_dir_fid,
17647                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17648                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17649
17650         { &hf_smb_alloc_size64,
17651                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17652                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17653
17654         { &hf_smb_nt_create_disposition,
17655                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17656                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17657
17658         { &hf_smb_sd_length,
17659                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17660                 NULL, 0, "Total length of security descriptor", HFILL }},
17661
17662         { &hf_smb_ea_list_length,
17663                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17664                 NULL, 0, "Total length of extended attributes", HFILL }},
17665
17666         { &hf_smb_ea_flags,
17667                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17668                 NULL, 0, "EA Flags", HFILL }},
17669
17670         { &hf_smb_ea_name_length,
17671                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17672                 NULL, 0, "EA Name Length", HFILL }},
17673
17674         { &hf_smb_ea_data_length,
17675                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17676                 NULL, 0, "EA Data Length", HFILL }},
17677
17678         { &hf_smb_ea_name,
17679                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17680                 NULL, 0, "EA Name", HFILL }},
17681
17682         { &hf_smb_ea_data,
17683                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17684                 NULL, 0, "EA Data", HFILL }},
17685
17686         { &hf_smb_file_name_len,
17687                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17688                 NULL, 0, "Length of File Name", HFILL }},
17689
17690         { &hf_smb_nt_impersonation_level,
17691                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17692                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17693
17694         { &hf_smb_nt_security_flags_context_tracking,
17695                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17696                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17697
17698         { &hf_smb_nt_security_flags_effective_only,
17699                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17700                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17701
17702         { &hf_smb_nt_access_mask_generic_read,
17703                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17704                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17705
17706         { &hf_smb_nt_access_mask_generic_write,
17707                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17708                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17709
17710         { &hf_smb_nt_access_mask_generic_execute,
17711                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17712                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17713
17714         { &hf_smb_nt_access_mask_generic_all,
17715                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17716                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17717
17718         { &hf_smb_nt_access_mask_maximum_allowed,
17719                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17720                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17721
17722         { &hf_smb_nt_access_mask_system_security,
17723                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17724                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17725
17726         { &hf_smb_nt_access_mask_synchronize,
17727                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17728                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17729
17730         { &hf_smb_nt_access_mask_write_owner,
17731                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17732                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17733
17734         { &hf_smb_nt_access_mask_write_dac,
17735                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17736                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17737
17738         { &hf_smb_nt_access_mask_read_control,
17739                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17740                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17741
17742         { &hf_smb_nt_access_mask_delete,
17743                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17744                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17745
17746         { &hf_smb_nt_access_mask_write_attributes,
17747                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17748                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17749
17750         { &hf_smb_nt_access_mask_read_attributes,
17751                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17752                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17753
17754         { &hf_smb_nt_access_mask_delete_child,
17755                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17756                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17757
17758         /*
17759          * "Execute" for files, "traverse" for directories.
17760          */
17761         { &hf_smb_nt_access_mask_execute,
17762                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17763                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17764
17765         { &hf_smb_nt_access_mask_write_ea,
17766                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17767                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17768
17769         { &hf_smb_nt_access_mask_read_ea,
17770                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17771                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17772
17773         /*
17774          * "Append data" for files, "add subdirectory" for directories,
17775          * "create pipe instance" for named pipes.
17776          */
17777         { &hf_smb_nt_access_mask_append,
17778                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17779                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17780
17781         /*
17782          * "Write data" for files and pipes, "add file" for directory.
17783          */
17784         { &hf_smb_nt_access_mask_write,
17785                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17786                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17787
17788         /*
17789          * "Read data" for files and pipes, "list directory" for directory.
17790          */
17791         { &hf_smb_nt_access_mask_read,
17792                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17793                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17794
17795         { &hf_smb_nt_create_bits_oplock,
17796                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17797                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17798
17799         { &hf_smb_nt_create_bits_boplock,
17800                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17801                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17802
17803         { &hf_smb_nt_create_bits_dir,
17804                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17805                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17806
17807         { &hf_smb_nt_create_bits_ext_resp,
17808           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
17809             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
17810
17811         { &hf_smb_nt_create_options_directory_file,
17812                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17813                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17814
17815         { &hf_smb_nt_create_options_write_through,
17816                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17817                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17818
17819         { &hf_smb_nt_create_options_sequential_only,
17820                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17821                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17822
17823         { &hf_smb_nt_create_options_no_intermediate_buffering,
17824                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
17825                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
17826
17827         { &hf_smb_nt_create_options_sync_io_alert,
17828                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17829                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17830
17831         { &hf_smb_nt_create_options_sync_io_nonalert,
17832                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17833                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17834
17835         { &hf_smb_nt_create_options_non_directory_file,
17836                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17837                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17838
17839         { &hf_smb_nt_create_options_create_tree_connection,
17840                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
17841                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
17842
17843         { &hf_smb_nt_create_options_complete_if_oplocked,
17844                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
17845                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
17846
17847         { &hf_smb_nt_create_options_no_ea_knowledge,
17848                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17849                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17850
17851         { &hf_smb_nt_create_options_eight_dot_three_only,
17852                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17853                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17854
17855         { &hf_smb_nt_create_options_random_access,
17856                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17857                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17858
17859         { &hf_smb_nt_create_options_delete_on_close,
17860                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17861                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17862         { &hf_smb_nt_create_options_open_by_fileid,
17863                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
17864                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
17865
17866         { &hf_smb_nt_create_options_backup_intent,
17867                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
17868                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
17869
17870         { &hf_smb_nt_create_options_no_compression,
17871                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
17872                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
17873
17874         { &hf_smb_nt_create_options_reserve_opfilter,
17875                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
17876                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
17877
17878         { &hf_smb_nt_create_options_open_reparse_point,
17879                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
17880                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
17881
17882         { &hf_smb_nt_create_options_open_no_recall,
17883                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
17884                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
17885
17886         { &hf_smb_nt_create_options_open_for_free_space_query,
17887                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
17888                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
17889
17890         { &hf_smb_nt_share_access_read,
17891                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17892                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
17893
17894         { &hf_smb_nt_share_access_write,
17895                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17896                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
17897
17898         { &hf_smb_nt_share_access_delete,
17899                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17900                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, "", HFILL }},
17901
17902         { &hf_smb_file_eattr_read_only,
17903                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17904                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17905
17906         { &hf_smb_file_eattr_hidden,
17907                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17908                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17909
17910         { &hf_smb_file_eattr_system,
17911                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17912                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17913
17914         { &hf_smb_file_eattr_volume,
17915                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
17916                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17917
17918         { &hf_smb_file_eattr_directory,
17919                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
17920                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17921
17922         { &hf_smb_file_eattr_archive,
17923                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17924                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17925
17926         { &hf_smb_file_eattr_device,
17927                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17928                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17929
17930         { &hf_smb_file_eattr_normal,
17931                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17932                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17933
17934         { &hf_smb_file_eattr_temporary,
17935                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17936                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17937
17938         { &hf_smb_file_eattr_sparse,
17939                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17940                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17941
17942         { &hf_smb_file_eattr_reparse,
17943                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17944                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17945
17946         { &hf_smb_file_eattr_compressed,
17947                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17948                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17949
17950         { &hf_smb_file_eattr_offline,
17951                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17952                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17953
17954         { &hf_smb_file_eattr_not_content_indexed,
17955                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17956                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17957
17958         { &hf_smb_file_eattr_encrypted,
17959                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17960                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17961
17962         { &hf_smb_sec_desc_len,
17963                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17964                 NULL, 0, "Security Descriptor Length", HFILL }},
17965
17966         { &hf_smb_nt_qsd_owner,
17967                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17968                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17969
17970         { &hf_smb_nt_qsd_group,
17971                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17972                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17973
17974         { &hf_smb_nt_qsd_dacl,
17975                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17976                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17977
17978         { &hf_smb_nt_qsd_sacl,
17979                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17980                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17981
17982         { &hf_smb_extended_attributes,
17983                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17984                 NULL, 0, "Extended Attributes", HFILL }},
17985
17986         { &hf_smb_oplock_level,
17987                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17988                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17989
17990         { &hf_smb_create_action,
17991                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17992                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
17993
17994         { &hf_smb_file_id,
17995                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17996                 NULL, 0, "Server unique file ID", HFILL }},
17997
17998         { &hf_smb_ea_error_offset,
17999                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18000                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18001
18002         { &hf_smb_end_of_file,
18003                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18004                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18005
18006         { &hf_smb_replace,
18007                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18008                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18009
18010         { &hf_smb_root_dir_handle,
18011                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18012                 NULL, 0, "Root directory handle", HFILL }},
18013
18014         { &hf_smb_target_name_len,
18015                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18016                 NULL, 0, "Length of target file name", HFILL }},
18017
18018         { &hf_smb_target_name,
18019                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18020                 NULL, 0, "Target file name", HFILL }},
18021
18022         { &hf_smb_device_type,
18023                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18024                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18025
18026         { &hf_smb_is_directory,
18027                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18028                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18029
18030         { &hf_smb_next_entry_offset,
18031                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18032                 NULL, 0, "Offset to next entry", HFILL }},
18033
18034         { &hf_smb_change_time,
18035                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18036                 NULL, 0, "Last Change Time", HFILL }},
18037
18038         { &hf_smb_setup_len,
18039                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18040                 NULL, 0, "Length of printer setup data", HFILL }},
18041
18042         { &hf_smb_print_mode,
18043                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18044                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18045
18046         { &hf_smb_print_identifier,
18047                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18048                 NULL, 0, "Identifier string for this print job", HFILL }},
18049
18050         { &hf_smb_restart_index,
18051                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18052                 NULL, 0, "Index of entry after last returned", HFILL }},
18053
18054         { &hf_smb_print_queue_date,
18055                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18056                 NULL, 0, "Date when this entry was queued", HFILL }},
18057
18058         { &hf_smb_print_queue_dos_date,
18059                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18060                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18061
18062         { &hf_smb_print_queue_dos_time,
18063                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18064                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18065
18066         { &hf_smb_print_status,
18067                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18068                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18069
18070         { &hf_smb_print_spool_file_number,
18071                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18072                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18073
18074         { &hf_smb_print_spool_file_size,
18075                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18076                 NULL, 0, "Number of bytes in spool file", HFILL }},
18077
18078         { &hf_smb_print_spool_file_name,
18079                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
18080                 NULL, 0, "Name of client that submitted this job", HFILL }},
18081
18082         { &hf_smb_start_index,
18083                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18084                 NULL, 0, "First queue entry to return", HFILL }},
18085
18086         { &hf_smb_originator_name,
18087                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18088                 NULL, 0, "Name of sender of message", HFILL }},
18089
18090         { &hf_smb_destination_name,
18091                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18092                 NULL, 0, "Name of recipient of message", HFILL }},
18093
18094         { &hf_smb_message_len,
18095                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18096                 NULL, 0, "Length of message", HFILL }},
18097
18098         { &hf_smb_message,
18099                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18100                 NULL, 0, "Message text", HFILL }},
18101
18102         { &hf_smb_mgid,
18103                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18104                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18105
18106         { &hf_smb_forwarded_name,
18107                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18108                 NULL, 0, "Recipient name being forwarded", HFILL }},
18109
18110         { &hf_smb_machine_name,
18111                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18112                 NULL, 0, "Name of target machine", HFILL }},
18113
18114         { &hf_smb_cancel_to,
18115                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18116                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18117
18118         { &hf_smb_trans_name,
18119                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18120                 NULL, 0, "Name of transaction", HFILL }},
18121
18122         { &hf_smb_transaction_flags_dtid,
18123                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18124                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18125
18126         { &hf_smb_transaction_flags_owt,
18127                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18128                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18129
18130         { &hf_smb_search_count,
18131                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18132                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18133
18134         { &hf_smb_search_pattern,
18135                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18136                 NULL, 0, "Search Pattern", HFILL }},
18137
18138         { &hf_smb_ff2_backup,
18139                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18140                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18141
18142         { &hf_smb_ff2_continue,
18143                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18144                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18145
18146         { &hf_smb_ff2_resume,
18147                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18148                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18149
18150         { &hf_smb_ff2_close_eos,
18151                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18152                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18153
18154         { &hf_smb_ff2_close,
18155                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18156                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18157
18158         { &hf_smb_ff2_information_level,
18159                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18160                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18161
18162         { &hf_smb_qpi_loi,
18163                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18164                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18165
18166         { &hf_smb_spi_loi,
18167                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18168                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18169
18170 #if 0
18171         { &hf_smb_sfi_writetru,
18172                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18173                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18174
18175         { &hf_smb_sfi_caching,
18176                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18177                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18178 #endif
18179
18180         { &hf_smb_storage_type,
18181                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18182                 NULL, 0, "Type of storage", HFILL }},
18183
18184         { &hf_smb_resume,
18185                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18186                 NULL, 0, "Resume Key", HFILL }},
18187
18188         { &hf_smb_max_referral_level,
18189                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18190                 NULL, 0, "Latest referral version number understood", HFILL }},
18191
18192         { &hf_smb_qfsi_information_level,
18193                 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
18194                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18195
18196         { &hf_smb_nt_rename_level,
18197                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18198                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18199
18200         { &hf_smb_cluster_count,
18201                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18202                 NULL, 0, "Number of clusters", HFILL }},
18203
18204         { &hf_smb_number_of_links,
18205                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18206                 NULL, 0, "Number of hard links to the file", HFILL }},
18207
18208         { &hf_smb_delete_pending,
18209                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18210                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18211
18212         { &hf_smb_index_number,
18213                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
18214                 NULL, 0, "File system unique identifier", HFILL }},
18215
18216         { &hf_smb_position,
18217                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
18218                 NULL, 0, "File position", HFILL }},
18219
18220         { &hf_smb_current_offset,
18221                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18222                 NULL, 0, "Current offset in the file", HFILL }},
18223
18224         { &hf_smb_t2_alignment,
18225                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18226                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18227
18228         { &hf_smb_t2_stream_name_length,
18229                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18230                 NULL, 0, "Length of stream name", HFILL }},
18231
18232         { &hf_smb_t2_stream_size,
18233                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18234                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18235
18236         { &hf_smb_t2_stream_name,
18237                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18238                 NULL, 0, "Name of the stream", HFILL }},
18239
18240         { &hf_smb_t2_compressed_file_size,
18241                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18242                 NULL, 0, "Size of the compressed file", HFILL }},
18243
18244         { &hf_smb_t2_compressed_format,
18245                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18246                 NULL, 0, "Compression algorithm used", HFILL }},
18247
18248         { &hf_smb_t2_compressed_unit_shift,
18249                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18250                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18251
18252         { &hf_smb_t2_compressed_chunk_shift,
18253                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18254                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18255
18256         { &hf_smb_t2_compressed_cluster_shift,
18257                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18258                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18259
18260         { &hf_smb_t2_marked_for_deletion,
18261                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18262                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18263
18264         { &hf_smb_dfs_path_consumed,
18265                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18266                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18267
18268         { &hf_smb_dfs_num_referrals,
18269                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18270                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18271
18272         { &hf_smb_get_dfs_server_hold_storage,
18273                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18274                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18275
18276         { &hf_smb_get_dfs_fielding,
18277                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18278                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18279
18280         { &hf_smb_dfs_referral_version,
18281                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18282                 NULL, 0, "Version of referral element", HFILL }},
18283
18284         { &hf_smb_dfs_referral_size,
18285                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18286                 NULL, 0, "Size of referral element", HFILL }},
18287
18288         { &hf_smb_dfs_referral_server_type,
18289                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18290                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18291
18292         { &hf_smb_dfs_referral_flags_strip,
18293                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18294                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18295
18296         { &hf_smb_dfs_referral_node_offset,
18297                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18298                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18299
18300         { &hf_smb_dfs_referral_node,
18301                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18302                 NULL, 0, "Name of entity to visit next", HFILL }},
18303
18304         { &hf_smb_dfs_referral_proximity,
18305                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18306                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18307
18308         { &hf_smb_dfs_referral_ttl,
18309                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18310                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18311
18312         { &hf_smb_dfs_referral_path_offset,
18313                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18314                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18315
18316         { &hf_smb_dfs_referral_path,
18317                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18318                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18319
18320         { &hf_smb_dfs_referral_alt_path_offset,
18321                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18322                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18323
18324         { &hf_smb_dfs_referral_alt_path,
18325                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18326                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18327
18328         { &hf_smb_end_of_search,
18329                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18330                 NULL, 0, "Was last entry returned?", HFILL }},
18331
18332         { &hf_smb_last_name_offset,
18333                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18334                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18335
18336         { &hf_smb_fn_information_level,
18337                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18338                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18339
18340         { &hf_smb_monitor_handle,
18341                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18342                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18343
18344         { &hf_smb_change_count,
18345                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18346                 NULL, 0, "Number of changes to wait for", HFILL }},
18347
18348         { &hf_smb_file_index,
18349                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18350                 NULL, 0, "File index", HFILL }},
18351
18352         { &hf_smb_short_file_name,
18353                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18354                 NULL, 0, "Short (8.3) File Name", HFILL }},
18355
18356         { &hf_smb_short_file_name_len,
18357                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18358                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18359
18360         { &hf_smb_fs_id,
18361                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18362                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18363
18364         { &hf_smb_sector_unit,
18365                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18366                 NULL, 0, "Sectors per allocation unit", HFILL }},
18367
18368         { &hf_smb_fs_units,
18369                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18370                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18371
18372         { &hf_smb_fs_sector,
18373                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18374                 NULL, 0, "Bytes per sector", HFILL }},
18375
18376         { &hf_smb_avail_units,
18377                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18378                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18379
18380         { &hf_smb_volume_serial_num,
18381                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18382                 NULL, 0, "Volume serial number", HFILL }},
18383
18384         { &hf_smb_volume_label_len,
18385                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18386                 NULL, 0, "Length of volume label", HFILL }},
18387
18388         { &hf_smb_volume_label,
18389                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18390                 NULL, 0, "Volume label", HFILL }},
18391
18392         { &hf_smb_free_alloc_units64,
18393                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18394                 NULL, 0, "Number of free allocation units", HFILL }},
18395
18396         { &hf_smb_caller_free_alloc_units64,
18397                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18398                 NULL, 0, "Number of caller free allocation units", HFILL }},
18399
18400         { &hf_smb_actual_free_alloc_units64,
18401                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18402                 NULL, 0, "Number of actual free allocation units", HFILL }},
18403
18404         { &hf_smb_soft_quota_limit,
18405                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18406                 NULL, 0, "Soft Quota treshold", HFILL }},
18407
18408         { &hf_smb_hard_quota_limit,
18409                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18410                 NULL, 0, "Hard Quota limit", HFILL }},
18411
18412         { &hf_smb_user_quota_used,
18413                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18414                 NULL, 0, "How much Quota is used by this user", HFILL }},
18415
18416         { &hf_smb_max_name_len,
18417                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18418                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18419
18420         { &hf_smb_fs_name_len,
18421                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18422                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18423
18424         { &hf_smb_fs_name,
18425                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18426                 NULL, 0, "Name of filesystem", HFILL }},
18427
18428         { &hf_smb_device_char_removable,
18429                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18430                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18431
18432         { &hf_smb_device_char_read_only,
18433                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18434                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18435
18436         { &hf_smb_device_char_floppy,
18437                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18438                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18439
18440         { &hf_smb_device_char_write_once,
18441                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18442                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18443
18444         { &hf_smb_device_char_remote,
18445                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18446                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18447
18448         { &hf_smb_device_char_mounted,
18449                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18450                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18451
18452         { &hf_smb_device_char_virtual,
18453                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18454                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18455
18456         { &hf_smb_fs_attr_css,
18457                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18458                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18459
18460         { &hf_smb_fs_attr_cpn,
18461                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18462                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18463
18464         { &hf_smb_fs_attr_uod,
18465                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
18466                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
18467
18468         { &hf_smb_fs_attr_pacls,
18469                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18470                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
18471
18472         { &hf_smb_fs_attr_fc,
18473                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18474                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
18475
18476         { &hf_smb_fs_attr_vq,
18477                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18478                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
18479
18480         { &hf_smb_fs_attr_ssf,
18481                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
18482                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
18483
18484         { &hf_smb_fs_attr_srp,
18485                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
18486                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
18487
18488         { &hf_smb_fs_attr_srs,
18489                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
18490                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
18491
18492         { &hf_smb_fs_attr_sla,
18493                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
18494                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
18495
18496         { &hf_smb_fs_attr_vic,
18497                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
18498                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
18499
18500         { &hf_smb_fs_attr_soids,
18501                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
18502                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
18503
18504         { &hf_smb_fs_attr_se,
18505                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
18506                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
18507
18508         { &hf_smb_fs_attr_ns,
18509                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
18510                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
18511
18512         { &hf_smb_fs_attr_rov,
18513                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
18514                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
18515
18516         { &hf_smb_user_quota_offset,
18517                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18518                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18519
18520         { &hf_smb_pipe_write_len,
18521                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18522                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18523
18524         { &hf_smb_quota_flags_deny_disk,
18525                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18526                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18527
18528         { &hf_smb_quota_flags_log_limit,
18529                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18530                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18531
18532         { &hf_smb_quota_flags_log_warning,
18533                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18534                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18535
18536         { &hf_smb_quota_flags_enabled,
18537                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18538                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18539
18540         { &hf_smb_segment_overlap,
18541                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18542                         "Fragment overlaps with other fragments", HFILL }},
18543
18544         { &hf_smb_segment_overlap_conflict,
18545                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18546                         "Overlapping fragments contained conflicting data", HFILL }},
18547
18548         { &hf_smb_segment_multiple_tails,
18549                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18550                         "Several tails were found when defragmenting the packet", HFILL }},
18551
18552         { &hf_smb_segment_too_long_fragment,
18553                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18554                         "Fragment contained data past end of packet", HFILL }},
18555
18556         { &hf_smb_segment_error,
18557                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18558                         "Defragmentation error due to illegal fragments", HFILL }},
18559
18560         { &hf_smb_opened_in,
18561                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18562                         "The frame this fid was opened", HFILL }},
18563
18564         { &hf_smb_closed_in,
18565                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18566                         "The frame this fid was closed", HFILL }},
18567
18568         { &hf_smb_mapped_in,
18569                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18570                         "The frame this share was mapped", HFILL }},
18571
18572         { &hf_smb_unmapped_in,
18573                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18574                         "The frame this share was unmapped", HFILL }},
18575
18576         { &hf_smb_segment,
18577                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18578                         "SMB Segment", HFILL }},
18579
18580         { &hf_smb_segments,
18581                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18582                         "SMB Segments", HFILL }},
18583
18584         { &hf_smb_unix_major_version,
18585           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18586             NULL, 0, "UNIX Major Version", HFILL }},
18587
18588         { &hf_smb_unix_minor_version,
18589           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18590             NULL, 0, "UNIX Minor Version", HFILL }},
18591
18592         { &hf_smb_unix_capability_fcntl,
18593           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18594                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18595
18596         { &hf_smb_unix_capability_posix_acl,
18597           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18598                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18599
18600         { &hf_smb_file_access_mask_read_data,
18601           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
18602                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18603
18604         { &hf_smb_file_access_mask_write_data,
18605           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
18606                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18607
18608         { &hf_smb_file_access_mask_append_data,
18609           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
18610                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18611
18612         { &hf_smb_file_access_mask_read_ea,
18613           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
18614                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18615
18616         { &hf_smb_file_access_mask_write_ea,
18617           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
18618                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18619
18620         { &hf_smb_file_access_mask_execute,
18621           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
18622                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18623
18624         { &hf_smb_file_access_mask_read_attribute,
18625           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
18626                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18627
18628         { &hf_smb_file_access_mask_write_attribute,
18629           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
18630                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18631
18632         { &hf_smb_dir_access_mask_list,
18633           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
18634                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18635
18636         { &hf_smb_dir_access_mask_add_file,
18637           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
18638                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18639
18640         { &hf_smb_dir_access_mask_add_subdir,
18641           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
18642                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18643
18644         { &hf_smb_dir_access_mask_read_ea,
18645           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
18646                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18647
18648         { &hf_smb_dir_access_mask_write_ea,
18649           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
18650                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18651
18652         { &hf_smb_dir_access_mask_traverse,
18653           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
18654                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18655
18656         { &hf_smb_dir_access_mask_delete_child,
18657           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
18658                 TFS(&flags_set_truth), 0x00000040, "", HFILL }},
18659
18660         { &hf_smb_dir_access_mask_read_attribute,
18661           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
18662                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18663
18664         { &hf_smb_dir_access_mask_write_attribute,
18665           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
18666                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18667
18668         { &hf_smb_unix_file_size,
18669           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18670             NULL, 0, "", HFILL }},
18671
18672         { &hf_smb_unix_file_num_bytes,
18673           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18674             NULL, 0, "Number of bytes used to store the file", HFILL }},
18675
18676         { &hf_smb_unix_file_last_status,
18677           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18678             NULL, 0, "", HFILL }},
18679
18680         { &hf_smb_unix_file_last_access,
18681           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18682             NULL, 0, "", HFILL }},
18683
18684         { &hf_smb_unix_file_last_change,
18685           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18686             NULL, 0, "", HFILL }},
18687
18688         { &hf_smb_unix_file_uid,
18689           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18690             NULL, 0, "", HFILL }},
18691
18692         { &hf_smb_unix_file_gid,
18693           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18694             NULL, 0, "", HFILL }},
18695
18696         { &hf_smb_unix_file_type,
18697           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18698             VALS(unix_file_type_vals), 0, "", HFILL }},
18699
18700         { &hf_smb_unix_file_dev_major,
18701           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18702             NULL, 0, "", HFILL }},
18703
18704         { &hf_smb_unix_file_dev_minor,
18705           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18706             NULL, 0, "", HFILL }},
18707
18708         { &hf_smb_unix_file_unique_id,
18709           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18710             NULL, 0, "", HFILL }},
18711
18712         { &hf_smb_unix_file_permissions,
18713           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18714             NULL, 0, "", HFILL }},
18715
18716         { &hf_smb_unix_file_nlinks,
18717           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18718             NULL, 0, "", HFILL }},
18719
18720         { &hf_smb_unix_file_link_dest,
18721           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
18722             BASE_NONE, NULL, 0, "", HFILL }},
18723
18724         { &hf_smb_unix_find_file_nextoffset,
18725           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18726             NULL, 0, "", HFILL }},
18727
18728         { &hf_smb_unix_find_file_resumekey,
18729           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18730             NULL, 0, "", HFILL }},
18731
18732         { &hf_smb_network_unknown,
18733           { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
18734             NULL, 0, "", HFILL }},
18735
18736         { &hf_smb_create_flags,
18737           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
18738             NULL, 0, "", HFILL }},
18739
18740         { &hf_smb_create_options,
18741           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
18742             NULL, 0, "", HFILL }},
18743
18744         { &hf_smb_share_access,
18745           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
18746             NULL, 0, "", HFILL }},
18747
18748         { &hf_smb_access_mask,
18749           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
18750             NULL, 0, "", HFILL }},
18751
18752         { &hf_smb_mode,
18753           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
18754             NULL, 0, "", HFILL }},
18755
18756         { &hf_smb_attribute,
18757           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
18758             NULL, 0, "", HFILL }},
18759
18760         { &hf_smb_reparse_tag,
18761           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
18762             NULL, 0, "", HFILL }},
18763
18764         { &hf_smb_disposition_delete_on_close,
18765           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
18766                 TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
18767
18768         { &hf_smb_pipe_info_flag,
18769           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
18770                 TFS(&tfs_pipe_info_flag), 0x01, "", HFILL }},
18771
18772         { &hf_smb_logged_in,
18773           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_DEC,
18774                 NULL, 0, "", HFILL }},
18775
18776         { &hf_smb_logged_out,
18777           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_DEC,
18778                 NULL, 0, "", HFILL }},
18779
18780         { &hf_smb_file_rw_offset,
18781           { "File Offset", "smb.file.rw.offset", FT_UINT32, BASE_DEC,
18782                 NULL, 0, "", HFILL }},
18783
18784         { &hf_smb_file_rw_length,
18785           { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
18786                 NULL, 0, "", HFILL }},
18787
18788         };
18789
18790         static gint *ett[] = {
18791                 &ett_smb,
18792                 &ett_smb_fid,
18793                 &ett_smb_tid,
18794                 &ett_smb_uid,
18795                 &ett_smb_hdr,
18796                 &ett_smb_command,
18797                 &ett_smb_fileattributes,
18798                 &ett_smb_capabilities,
18799                 &ett_smb_aflags,
18800                 &ett_smb_dialect,
18801                 &ett_smb_dialects,
18802                 &ett_smb_mode,
18803                 &ett_smb_rawmode,
18804                 &ett_smb_flags,
18805                 &ett_smb_flags2,
18806                 &ett_smb_desiredaccess,
18807                 &ett_smb_search,
18808                 &ett_smb_file,
18809                 &ett_smb_openfunction,
18810                 &ett_smb_filetype,
18811                 &ett_smb_openaction,
18812                 &ett_smb_writemode,
18813                 &ett_smb_lock_type,
18814                 &ett_smb_ssetupandxaction,
18815                 &ett_smb_optionsup,
18816                 &ett_smb_time_date,
18817                 &ett_smb_move_copy_flags,
18818                 &ett_smb_file_attributes,
18819                 &ett_smb_search_resume_key,
18820                 &ett_smb_search_dir_info,
18821                 &ett_smb_unlocks,
18822                 &ett_smb_unlock,
18823                 &ett_smb_locks,
18824                 &ett_smb_lock,
18825                 &ett_smb_open_flags,
18826                 &ett_smb_ipc_state,
18827                 &ett_smb_open_action,
18828                 &ett_smb_setup_action,
18829                 &ett_smb_connect_flags,
18830                 &ett_smb_connect_support_bits,
18831                 &ett_smb_nt_access_mask,
18832                 &ett_smb_nt_create_bits,
18833                 &ett_smb_nt_create_options,
18834                 &ett_smb_nt_share_access,
18835                 &ett_smb_nt_security_flags,
18836                 &ett_smb_nt_trans_setup,
18837                 &ett_smb_nt_trans_data,
18838                 &ett_smb_nt_trans_param,
18839                 &ett_smb_nt_notify_completion_filter,
18840                 &ett_smb_nt_ioctl_flags,
18841                 &ett_smb_security_information_mask,
18842                 &ett_smb_print_queue_entry,
18843                 &ett_smb_transaction_flags,
18844                 &ett_smb_transaction_params,
18845                 &ett_smb_find_first2_flags,
18846 #if 0
18847                 &ett_smb_ioflag,
18848 #endif
18849                 &ett_smb_transaction_data,
18850                 &ett_smb_stream_info,
18851                 &ett_smb_dfs_referrals,
18852                 &ett_smb_dfs_referral,
18853                 &ett_smb_dfs_referral_flags,
18854                 &ett_smb_get_dfs_flags,
18855                 &ett_smb_ff2_data,
18856                 &ett_smb_device_characteristics,
18857                 &ett_smb_fs_attributes,
18858                 &ett_smb_segments,
18859                 &ett_smb_segment,
18860                 &ett_smb_quotaflags,
18861                 &ett_smb_secblob,
18862                 &ett_smb_mac_support_flags,
18863                 &ett_smb_unicode_password,
18864                 &ett_smb_ea,
18865                 &ett_smb_unix_capabilities
18866         };
18867         module_t *smb_module;
18868
18869         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
18870             "SMB", "smb");
18871         proto_register_subtree_array(ett, array_length(ett));
18872         proto_register_field_array(proto_smb, hf, array_length(hf));
18873
18874         proto_do_register_windows_common(proto_smb);
18875
18876         register_init_routine(&smb_init_protocol);
18877         smb_module = prefs_register_protocol(proto_smb, NULL);
18878         prefs_register_bool_preference(smb_module, "trans_reassembly",
18879                 "Reassemble SMB Transaction payload",
18880                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
18881                 &smb_trans_reassembly);
18882         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
18883                 "Reassemble DCERPC over SMB",
18884                 "Whether the dissector should reassemble DCERPC over SMB commands",
18885                 &smb_dcerpc_reassembly);
18886         prefs_register_bool_preference(smb_module, "sid_name_snooping",
18887                 "Snoop SID to Name mappings",
18888                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
18889                 &sid_name_snooping);
18890
18891         register_init_routine(smb_trans_reassembly_init);
18892         smb_tap = register_tap("smb");
18893 }
18894
18895 void
18896 proto_reg_handoff_smb(void)
18897 {
18898         dissector_handle_t smb_handle;
18899
18900         gssapi_handle = find_dissector("gssapi");
18901         ntlmssp_handle = find_dissector("ntlmssp");
18902
18903         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
18904         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
18905         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
18906         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
18907         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
18908         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
18909         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
18910             smb_handle);
18911         dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
18912 }