track FIDs on a per transaction (request+response) basis and make sure the FID is...
[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
662 static gint ett_smb = -1;
663 static gint ett_smb_fid = -1;
664 static gint ett_smb_tid = -1;
665 static gint ett_smb_uid = -1;
666 static gint ett_smb_hdr = -1;
667 static gint ett_smb_command = -1;
668 static gint ett_smb_fileattributes = -1;
669 static gint ett_smb_capabilities = -1;
670 static gint ett_smb_aflags = -1;
671 static gint ett_smb_dialect = -1;
672 static gint ett_smb_dialects = -1;
673 static gint ett_smb_mode = -1;
674 static gint ett_smb_rawmode = -1;
675 static gint ett_smb_flags = -1;
676 static gint ett_smb_flags2 = -1;
677 static gint ett_smb_desiredaccess = -1;
678 static gint ett_smb_search = -1;
679 static gint ett_smb_file = -1;
680 static gint ett_smb_openfunction = -1;
681 static gint ett_smb_filetype = -1;
682 static gint ett_smb_openaction = -1;
683 static gint ett_smb_writemode = -1;
684 static gint ett_smb_lock_type = -1;
685 static gint ett_smb_ssetupandxaction = -1;
686 static gint ett_smb_optionsup = -1;
687 static gint ett_smb_time_date = -1;
688 static gint ett_smb_move_copy_flags = -1;
689 static gint ett_smb_file_attributes = -1;
690 static gint ett_smb_search_resume_key = -1;
691 static gint ett_smb_search_dir_info = -1;
692 static gint ett_smb_unlocks = -1;
693 static gint ett_smb_unlock = -1;
694 static gint ett_smb_locks = -1;
695 static gint ett_smb_lock = -1;
696 static gint ett_smb_open_flags = -1;
697 static gint ett_smb_ipc_state = -1;
698 static gint ett_smb_open_action = -1;
699 static gint ett_smb_setup_action = -1;
700 static gint ett_smb_connect_flags = -1;
701 static gint ett_smb_connect_support_bits = -1;
702 static gint ett_smb_nt_access_mask = -1;
703 static gint ett_smb_nt_create_bits = -1;
704 static gint ett_smb_nt_create_options = -1;
705 static gint ett_smb_nt_share_access = -1;
706 static gint ett_smb_nt_security_flags = -1;
707 static gint ett_smb_nt_trans_setup = -1;
708 static gint ett_smb_nt_trans_data = -1;
709 static gint ett_smb_nt_trans_param = -1;
710 static gint ett_smb_nt_notify_completion_filter = -1;
711 static gint ett_smb_nt_ioctl_flags = -1;
712 static gint ett_smb_security_information_mask = -1;
713 static gint ett_smb_print_queue_entry = -1;
714 static gint ett_smb_transaction_flags = -1;
715 static gint ett_smb_transaction_params = -1;
716 static gint ett_smb_find_first2_flags = -1;
717 static gint ett_smb_mac_support_flags = -1;
718 #if 0
719 static gint ett_smb_ioflag = -1;
720 #endif
721 static gint ett_smb_transaction_data = -1;
722 static gint ett_smb_stream_info = -1;
723 static gint ett_smb_dfs_referrals = -1;
724 static gint ett_smb_dfs_referral = -1;
725 static gint ett_smb_dfs_referral_flags = -1;
726 static gint ett_smb_get_dfs_flags = -1;
727 static gint ett_smb_ff2_data = -1;
728 static gint ett_smb_device_characteristics = -1;
729 static gint ett_smb_fs_attributes = -1;
730 static gint ett_smb_segments = -1;
731 static gint ett_smb_segment = -1;
732 static gint ett_smb_quotaflags = -1;
733 static gint ett_smb_secblob = -1;
734 static gint ett_smb_unicode_password = -1;
735 static gint ett_smb_ea = -1;
736 static gint ett_smb_unix_capabilities = -1;
737
738 static int smb_tap = -1;
739
740 static dissector_handle_t gssapi_handle = NULL;
741 static dissector_handle_t ntlmssp_handle = NULL;
742
743 static const fragment_items smb_frag_items = {
744         &ett_smb_segment,
745         &ett_smb_segments,
746
747         &hf_smb_segments,
748         &hf_smb_segment,
749         &hf_smb_segment_overlap,
750         &hf_smb_segment_overlap_conflict,
751         &hf_smb_segment_multiple_tails,
752         &hf_smb_segment_too_long_fragment,
753         &hf_smb_segment_error,
754         NULL,
755
756         "segments"
757 };
758
759 static proto_tree *top_tree=NULL;     /* ugly */
760
761 static const char *decode_smb_name(guint8);
762 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
763
764 /*
765  * Macros for use in the main dissector routines for an SMB.
766  */
767
768 #define WORD_COUNT      \
769         /* Word Count */                                \
770         wc = tvb_get_guint8(tvb, offset);               \
771         proto_tree_add_uint(tree, hf_smb_word_count,    \
772                 tvb, offset, 1, wc);                    \
773         offset += 1;                                    \
774         if(wc==0) goto bytecount;
775
776 #define BYTE_COUNT      \
777         bytecount:                                      \
778         bc = tvb_get_letohs(tvb, offset);               \
779         proto_tree_add_uint(tree, hf_smb_byte_count,    \
780                         tvb, offset, 2, bc);            \
781         offset += 2;                                    \
782         if(bc==0) goto endofcommand;
783
784 #define CHECK_BYTE_COUNT(len)   \
785         if (bc < len) goto endofcommand;
786
787 #define COUNT_BYTES(len)   {\
788         int tmp;            \
789         tmp=len;            \
790         offset += tmp;      \
791         bc -= tmp;          \
792         }
793
794 #define END_OF_SMB      \
795         if (bc != 0) { \
796                 gint bc_remaining; \
797                 bc_remaining=tvb_length_remaining(tvb, offset); \
798                 if( ((gint)bc) > bc_remaining){ \
799                         bc=bc_remaining; \
800                 } \
801                 if(bc){ \
802                         tvb_ensure_bytes_exist(tvb, offset, bc); \
803                         proto_tree_add_text(tree, tvb, offset, bc, \
804                             "Extra byte parameters");           \
805                 } \
806                 offset += bc;                           \
807         }                                               \
808         endofcommand:
809
810 /*
811  * Macros for use in routines called by them.
812  */
813 #define CHECK_BYTE_COUNT_SUBR(len)      \
814         if (*bcp < len) {               \
815                 *trunc = TRUE;          \
816                 return offset;          \
817         }
818
819 #define CHECK_STRING_SUBR(fn)   \
820         if (fn == NULL) {       \
821                 *trunc = TRUE;  \
822                 return offset;  \
823         }
824
825 #define COUNT_BYTES_SUBR(len)   \
826         offset += len;          \
827         *bcp -= len;
828
829 /*
830  * Macros for use when dissecting transaction parameters and data
831  */
832 #define CHECK_BYTE_COUNT_TRANS(len)     \
833         if (bc < len) return offset;
834
835 #define CHECK_STRING_TRANS(fn)  \
836         if (fn == NULL) return offset;
837
838 #define COUNT_BYTES_TRANS(len)  \
839         offset += len;          \
840         bc -= len;
841
842 /*
843  * Macros for use in subrroutines dissecting transaction parameters or data
844  */
845 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
846         if (*bcp < len) return offset;
847
848 #define CHECK_STRING_TRANS_SUBR(fn)     \
849         if (fn == NULL) return offset;
850
851 #define COUNT_BYTES_TRANS_SUBR(len)     \
852         offset += len;                  \
853         *bcp -= len;
854
855
856 gboolean sid_name_snooping = FALSE;
857
858 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
859    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
860    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
861 static gboolean smb_trans_reassembly = TRUE;
862 gboolean smb_dcerpc_reassembly = TRUE;
863
864 static GHashTable *smb_trans_fragment_table = NULL;
865
866 static void
867 smb_trans_reassembly_init(void)
868 {
869         fragment_table_init(&smb_trans_fragment_table);
870 }
871
872 /*
873  * XXX - This keeps us from allocating huge amounts of memory as shown in
874  * bug 421.  It may need to be increased.
875  */
876 #define MAX_FRAGMENT_SIZE 65536
877 static fragment_data *
878 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
879                      int offset, int count, int pos, int totlen)
880 {
881         fragment_data *fd_head=NULL;
882         smb_info_t *si;
883         int more_frags;
884
885         if (count > MAX_FRAGMENT_SIZE || count < 0) {
886                 THROW(ReportedBoundsError);
887         }
888
889         more_frags=totlen>(pos+count);
890
891         si = (smb_info_t *)pinfo->private_data;
892         DISSECTOR_ASSERT(si);
893
894         if (si->sip == NULL) {
895                 /*
896                  * We don't have the frame number of the request.
897                  */
898                 return NULL;
899         }
900
901         if(!pinfo->fd->flags.visited){
902                 fd_head = fragment_add(tvb, offset, pinfo,
903                                        si->sip->frame_req, smb_trans_fragment_table,
904                                        pos, count, more_frags);
905         } else {
906                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
907         }
908
909         if (!fd_head || !(fd_head->flags&FD_DEFRAGMENTED)){
910                 /* This is continued - mark it as such, so we recognize
911                    continuation responses.
912                 */
913                 si->sip->flags |= SMB_SIF_IS_CONTINUED;
914         } else {
915                 /* We've finished reassembling, so there are no more
916                    continuation responses.
917                 */
918                 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
919         }
920
921         /* we only show the defragmented packet for the first fragment,
922            or else we might end up with dissecting one HUGE transaction PDU
923            a LOT of times. (first fragment is the only one containing the setup
924            bytes)
925            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
926            SMBs. Takes a LOT of time dissecting and is not fun.
927         */
928         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
929                 return fd_head;
930         } else {
931                 return NULL;
932         }
933 }
934
935
936
937
938
939 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
940    These variables and functions are used to match
941    responses with calls
942    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
943 /*
944  * The information we need to save about a request in order to show the
945  * frame number of the request in the dissection of the reply.
946  */
947 typedef struct  {
948         guint32 frame;
949         guint32 pid_mid;
950 } smb_saved_info_key_t;
951
952 /* unmatched smb_saved_info structures.
953    For unmatched smb_saved_info structures we store the smb_saved_info
954    structure using the MID and the PID as the key.
955
956    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
957    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
958    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
959 */
960 static gint
961 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
962 {
963         register guint32 key1 = GPOINTER_TO_UINT(k1);
964         register guint32 key2 = GPOINTER_TO_UINT(k2);
965         return key1==key2;
966 }
967 static guint
968 smb_saved_info_hash_unmatched(gconstpointer k)
969 {
970         register guint32 key = GPOINTER_TO_UINT(k);
971         return key;
972 }
973
974 /* matched smb_saved_info structures.
975    For matched smb_saved_info structures we store the smb_saved_info
976    structure twice in the table using the frame number, and a combination
977    of the MID and the PID, as the key.
978    The frame number is guaranteed to be unique but if ever someone makes
979    some change that will renumber the frames in a capture we are in BIG trouble.
980    This is not likely though since that would break (among other things) all the
981    reassembly routines as well.
982
983    We also need the MID as there may be more than one SMB request or reply
984    in a single frame, and we also need the PID as there may be more than
985    one outstanding request with the same MID and different PIDs.
986 */
987 static gint
988 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
989 {
990         const smb_saved_info_key_t *key1 = k1;
991         const smb_saved_info_key_t *key2 = k2;
992         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
993 }
994 static guint
995 smb_saved_info_hash_matched(gconstpointer k)
996 {
997         const smb_saved_info_key_t *key = k;
998         return key->frame + key->pid_mid;
999 }
1000
1001 static GSList *conv_tables = NULL;
1002
1003
1004 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1005    End of request/response matching functions
1006    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1007
1008
1009
1010 typedef struct _smb_uid_t {
1011         char *domain;
1012         char *account;
1013         int logged_in;
1014         int logged_out;
1015 } smb_uid_t;
1016
1017 static void
1018 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1019 {
1020         mask&=0x0000ffff;
1021         if(mask==0x000001ff){
1022                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1023         }
1024
1025
1026         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1027         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1028         proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1029         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1030         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1031         proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1032         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1033         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1034 }
1035 struct access_mask_info smb_file_access_mask_info = {
1036         "FILE",                         /* Name of specific rights */
1037         smb_file_specific_rights,       /* Dissection function */
1038         NULL,                           /* Generic mapping table */
1039         NULL                            /* Standard mapping table */
1040 };
1041
1042
1043 static void
1044 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1045 {
1046         mask&=0x0000ffff;
1047         if(mask==0x000001ff){
1048                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1049         }
1050
1051
1052         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1053         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1054         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1055         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1056         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1057         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1058         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1059         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1060         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1061 }
1062 struct access_mask_info smb_dir_access_mask_info = {
1063         "DIR",                          /* Name of specific rights */
1064         smb_dir_specific_rights,        /* Dissection function */
1065         NULL,                           /* Generic mapping table */
1066         NULL                            /* Standard mapping table */
1067 };
1068
1069
1070
1071 static const value_string buffer_format_vals[] = {
1072         {1,     "Data Block"},
1073         {2,     "Dialect"},
1074         {3,     "Pathname"},
1075         {4,     "ASCII"},
1076         {5,     "Variable Block"},
1077         {0,     NULL}
1078 };
1079
1080 /*
1081  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1082  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1083  * January 1, 1970, 00:00:00 GMT.
1084  *
1085  * This means we have to do some extra work to convert it.  This code is
1086  * based on the Samba code:
1087  *
1088  *      Unix SMB/Netbios implementation.
1089  *      Version 1.9.
1090  *      time handling functions
1091  *      Copyright (C) Andrew Tridgell 1992-1998
1092  */
1093
1094 /*
1095  * Yield the difference between *A and *B, in seconds, ignoring leap
1096  * seconds.
1097  */
1098 #define TM_YEAR_BASE 1900
1099
1100 static int
1101 tm_diff(struct tm *a, struct tm *b)
1102 {
1103         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1104         int by = b->tm_year + (TM_YEAR_BASE - 1);
1105         int intervening_leap_days =
1106             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1107         int years = ay - by;
1108         int days =
1109             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1110         int hours = 24*days + (a->tm_hour - b->tm_hour);
1111         int minutes = 60*hours + (a->tm_min - b->tm_min);
1112         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1113
1114         return seconds;
1115 }
1116
1117 /*
1118  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1119  * determined.
1120  */
1121 static int
1122 TimeZone(time_t t)
1123 {
1124         struct tm *tm = gmtime(&t);
1125         struct tm tm_utc;
1126
1127         if (tm == NULL)
1128                 return 0;
1129         tm_utc = *tm;
1130         tm = localtime(&t);
1131         if (tm == NULL)
1132                 return 0;
1133         return tm_diff(&tm_utc,tm);
1134 }
1135
1136 /*
1137  * Return the same value as TimeZone, but it should be more efficient.
1138  *
1139  * We keep a table of DST offsets to prevent calling localtime() on each
1140  * call of this function. This saves a LOT of time on many unixes.
1141  *
1142  * Updated by Paul Eggert <eggert@twinsun.com>
1143  */
1144 #ifndef CHAR_BIT
1145 #define CHAR_BIT 8
1146 #endif
1147
1148 #ifndef TIME_T_MIN
1149 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1150                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1151 #endif
1152 #ifndef TIME_T_MAX
1153 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1154 #endif
1155
1156 static int
1157 TimeZoneFaster(time_t t)
1158 {
1159         static struct dst_table {time_t start,end; int zone;} *tdt;
1160         static struct dst_table *dst_table = NULL;
1161         static int table_size = 0;
1162         int i;
1163         int zone = 0;
1164
1165         if (t == 0)
1166                 t = time(NULL);
1167
1168         /* Tunis has a 8 day DST region, we need to be careful ... */
1169 #define MAX_DST_WIDTH (365*24*60*60)
1170 #define MAX_DST_SKIP (7*24*60*60)
1171
1172         for (i = 0; i < table_size; i++) {
1173                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1174                         break;
1175         }
1176
1177         if (i < table_size) {
1178                 zone = dst_table[i].zone;
1179         } else {
1180                 time_t low,high;
1181
1182                 zone = TimeZone(t);
1183                 if (dst_table == NULL)
1184                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1185                 else
1186                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1187                 if (tdt == NULL) {
1188                         if (dst_table)
1189                                 g_free(dst_table);
1190                         table_size = 0;
1191                 } else {
1192                         dst_table = tdt;
1193                         table_size++;
1194
1195                         dst_table[i].zone = zone;
1196                         dst_table[i].start = dst_table[i].end = t;
1197
1198                         /* no entry will cover more than 6 months */
1199                         low = t - MAX_DST_WIDTH/2;
1200                         if (t < low)
1201                                 low = TIME_T_MIN;
1202
1203                         high = t + MAX_DST_WIDTH/2;
1204                         if (high < t)
1205                                 high = TIME_T_MAX;
1206
1207                         /*
1208                          * Widen the new entry using two bisection searches.
1209                          */
1210                         while (low+60*60 < dst_table[i].start) {
1211                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1212                                         t = dst_table[i].start - MAX_DST_SKIP;
1213                                 else
1214                                         t = low + (dst_table[i].start-low)/2;
1215                                 if (TimeZone(t) == zone)
1216                                         dst_table[i].start = t;
1217                                 else
1218                                         low = t;
1219                         }
1220
1221                         while (high-60*60 > dst_table[i].end) {
1222                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1223                                         t = dst_table[i].end + MAX_DST_SKIP;
1224                                 else
1225                                         t = high - (high-dst_table[i].end)/2;
1226                                 if (TimeZone(t) == zone)
1227                                         dst_table[i].end = t;
1228                                 else
1229                                         high = t;
1230                         }
1231                 }
1232         }
1233         return zone;
1234 }
1235
1236 /*
1237  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1238  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1239  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1240  * daylight savings transitions because some local times are ambiguous.
1241  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1242  */
1243 static int
1244 LocTimeDiff(time_t lt)
1245 {
1246         int d = TimeZoneFaster(lt);
1247         time_t t = lt + d;
1248
1249         /* if overflow occurred, ignore all the adjustments so far */
1250         if (((t < lt) ^ (d < 0)))
1251                 t = lt;
1252
1253         /*
1254          * Now t should be close enough to the true UTC to yield the
1255          * right answer.
1256          */
1257         return TimeZoneFaster(t);
1258 }
1259
1260 static int
1261 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1262 {
1263         guint32 timeval;
1264         nstime_t ts;
1265
1266         timeval = tvb_get_letohl(tvb, offset);
1267         if (timeval == 0xffffffff) {
1268                 proto_tree_add_text(tree, tvb, offset, 4,
1269                     "%s: No time specified (0xffffffff)",
1270                     proto_registrar_get_name(hf_date));
1271                 offset += 4;
1272                 return offset;
1273         }
1274
1275         /*
1276          * We add the local time offset.
1277          */
1278         ts.secs = timeval + LocTimeDiff(timeval);
1279         ts.nsecs = 0;
1280
1281         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1282         offset += 4;
1283
1284         return offset;
1285 }
1286
1287 static int
1288 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1289     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1290 {
1291         guint16 dos_time, dos_date;
1292         proto_item *item = NULL;
1293         proto_tree *tree = NULL;
1294         struct tm tm;
1295         time_t t;
1296         static const int mday_noleap[12] = {
1297                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1298         };
1299         static const int mday_leap[12] = {
1300                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1301         };
1302 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1303         nstime_t tv;
1304
1305         if (time_first) {
1306                 dos_time = tvb_get_letohs(tvb, offset);
1307                 dos_date = tvb_get_letohs(tvb, offset+2);
1308         } else {
1309                 dos_date = tvb_get_letohs(tvb, offset);
1310                 dos_time = tvb_get_letohs(tvb, offset+2);
1311         }
1312
1313         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1314             (dos_date == 0 && dos_time == 0)) {
1315                 /*
1316                  * No date/time specified.
1317                  */
1318                 if(parent_tree){
1319                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1320                             "%s: No time specified (0x%08x)",
1321                             proto_registrar_get_name(hf_date),
1322                             (dos_date << 16) | dos_time);
1323                 }
1324                 offset += 4;
1325                 return offset;
1326         }
1327
1328         tm.tm_sec = (dos_time&0x1f)*2;
1329         tm.tm_min = (dos_time>>5)&0x3f;
1330         tm.tm_hour = (dos_time>>11)&0x1f;
1331         tm.tm_mday = dos_date&0x1f;
1332         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1333         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1334         tm.tm_isdst = -1;
1335
1336         /*
1337          * Do some sanity checks before calling "mktime()";
1338          * "mktime()" doesn't do them, it "normalizes" out-of-range
1339          * values.
1340          */
1341         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1342            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1343            (ISLEAP(tm.tm_year + 1900) ?
1344              tm.tm_mday > mday_leap[tm.tm_mon] :
1345              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1346              (t = mktime(&tm)) == -1) {
1347                 /*
1348                  * Invalid date/time.
1349                  */
1350                 if (parent_tree) {
1351                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1352                             "%s: Invalid time",
1353                             proto_registrar_get_name(hf_date));
1354                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1355                         if (time_first) {
1356                                 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);
1357                                 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);
1358                         } else {
1359                                 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);
1360                                 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);
1361                         }
1362                 }
1363                 offset += 4;
1364                 return offset;
1365         }
1366
1367         tv.secs = t;
1368         tv.nsecs = 0;
1369
1370         if(parent_tree){
1371                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1372                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1373                 if (time_first) {
1374                         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);
1375                         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);
1376                 } else {
1377                         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);
1378                         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);
1379                 }
1380         }
1381
1382         offset += 4;
1383
1384         return offset;
1385 }
1386
1387 static const true_false_string tfs_disposition_delete_on_close = {
1388         "DELETE this file when closed",
1389         "Normal access, do not delete on close"
1390 };
1391
1392 static const true_false_string tfs_pipe_info_flag = {
1393         "SET NAMED PIPE mode",
1394         "Clear NAMED PIPE mode"
1395 };
1396
1397
1398 static const value_string da_access_vals[] = {
1399         { 0,            "Open for reading"},
1400         { 1,            "Open for writing"},
1401         { 2,            "Open for reading and writing"},
1402         { 3,            "Open for execute"},
1403         {0, NULL}
1404 };
1405 static const value_string da_sharing_vals[] = {
1406         { 0,            "Compatibility mode"},
1407         { 1,            "Deny read/write/execute (exclusive)"},
1408         { 2,            "Deny write"},
1409         { 3,            "Deny read/execute"},
1410         { 4,            "Deny none"},
1411         {0, NULL}
1412 };
1413 static const value_string da_locality_vals[] = {
1414         { 0,            "Locality of reference unknown"},
1415         { 1,            "Mainly sequential access"},
1416         { 2,            "Mainly random access"},
1417         { 3,            "Random access with some locality"},
1418         {0, NULL}
1419 };
1420 static const true_false_string tfs_da_caching = {
1421         "Do not cache this file",
1422         "Caching permitted on this file"
1423 };
1424 static const true_false_string tfs_da_writetru = {
1425         "Write through enabled",
1426         "Write through disabled"
1427 };
1428 static int
1429 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1430 {
1431         guint16 mask;
1432         proto_item *item = NULL;
1433         proto_tree *tree = NULL;
1434
1435         mask = tvb_get_letohs(tvb, offset);
1436
1437         if(parent_tree){
1438                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1439                         "%s Access: 0x%04x", type, mask);
1440                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1441         }
1442
1443         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1444                 tvb, offset, 2, mask);
1445         proto_tree_add_boolean(tree, hf_smb_access_caching,
1446                 tvb, offset, 2, mask);
1447         proto_tree_add_uint(tree, hf_smb_access_locality,
1448                 tvb, offset, 2, mask);
1449         proto_tree_add_uint(tree, hf_smb_access_sharing,
1450                 tvb, offset, 2, mask);
1451         proto_tree_add_uint(tree, hf_smb_access_mode,
1452                 tvb, offset, 2, mask);
1453
1454         offset += 2;
1455
1456         return offset;
1457 }
1458
1459 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1460 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1461 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1462 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1463 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1464 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1465 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1466 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1467 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1468 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1469 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1470 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1471 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1472 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1473 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1474
1475 static const true_false_string tfs_file_attribute_read_only = {
1476         "This file is READ ONLY",
1477         "This file is NOT read only",
1478 };
1479 static const true_false_string tfs_file_attribute_hidden = {
1480         "This is a HIDDEN file",
1481         "This is NOT a hidden file"
1482 };
1483 static const true_false_string tfs_file_attribute_system = {
1484         "This is a SYSTEM file",
1485         "This is NOT a system file"
1486 };
1487 static const true_false_string tfs_file_attribute_volume = {
1488         "This is a VOLUME ID",
1489         "This is NOT a volume ID"
1490 };
1491 static const true_false_string tfs_file_attribute_directory = {
1492         "This is a DIRECTORY",
1493         "This is NOT a directory"
1494 };
1495 static const true_false_string tfs_file_attribute_archive = {
1496         "This file has been modified since last ARCHIVE",
1497         "This file has NOT been modified since last archive"
1498 };
1499 static const true_false_string tfs_file_attribute_device = {
1500         "This is a DEVICE",
1501         "This is NOT a device"
1502 };
1503 static const true_false_string tfs_file_attribute_normal = {
1504         "This file is an ordinary file",
1505         "This file has some attribute set"
1506 };
1507 static const true_false_string tfs_file_attribute_temporary = {
1508         "This is a TEMPORARY file",
1509         "This is NOT a temporary file"
1510 };
1511 static const true_false_string tfs_file_attribute_sparse = {
1512         "This is a SPARSE file",
1513         "This is NOT a sparse file"
1514 };
1515 static const true_false_string tfs_file_attribute_reparse = {
1516         "This file has an associated REPARSE POINT",
1517         "This file does NOT have an associated reparse point"
1518 };
1519 static const true_false_string tfs_file_attribute_compressed = {
1520         "This is a COMPRESSED file",
1521         "This is NOT a compressed file"
1522 };
1523 static const true_false_string tfs_file_attribute_offline = {
1524         "This file is OFFLINE",
1525         "This file is NOT offline"
1526 };
1527 static const true_false_string tfs_file_attribute_not_content_indexed = {
1528         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1529         "This file MAY be indexed by the content indexing service"
1530 };
1531 static const true_false_string tfs_file_attribute_encrypted = {
1532         "This is an ENCRYPTED file",
1533         "This is NOT an encrypted file"
1534 };
1535
1536 /*
1537  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1538  * listed as USHORT, and seem to be in packets in the wild, while in other
1539  * places they are listed as ULONG, and also seem to be.
1540  *
1541  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1542  * bytes to consume.
1543  */
1544
1545 int
1546 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1547                         int bytes)
1548 {
1549         guint16 mask;
1550         proto_item *item = NULL;
1551         proto_tree *tree = NULL;
1552
1553         if (bytes != 2 && bytes != 4) {
1554                 THROW(ReportedBoundsError);
1555         }
1556
1557         /*
1558          * The actual bits of interest appear to only be a USHORT
1559          */
1560         /* FIXME if this ever changes! */
1561         mask = tvb_get_letohs(tvb, offset);
1562
1563         if(parent_tree){
1564                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1565                         "File Attributes: 0x%08x", mask);
1566                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1567         }
1568         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1569                                tvb, offset, bytes, mask);       
1570         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1571                                tvb, offset, bytes, mask);
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1573                                tvb, offset, bytes, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1575                                tvb, offset, bytes, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1577                                tvb, offset, bytes, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1579                                tvb, offset, bytes, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1581                                tvb, offset, bytes, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1583                                tvb, offset, bytes, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1585                                tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1587                 tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1589                 tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1591                 tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1593                 tvb, offset, bytes, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1595                 tvb, offset, bytes, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1597                 tvb, offset, bytes, mask);
1598
1599         offset += bytes;
1600
1601         return offset;
1602 }
1603
1604 /* 3.11 */
1605 static int
1606 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset, guint32 mask)
1607 {
1608         proto_item *item = NULL;
1609         proto_tree *tree = NULL;
1610
1611         if(parent_tree){
1612                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1613                         "File Attributes: 0x%08x", mask);
1614                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1615         }
1616
1617         /*
1618          * XXX - Network Monitor disagrees on some of the
1619          * bits, e.g. the bits above temporary are "atomic write"
1620          * and "transaction write", and it says nothing about the
1621          * bits above that.
1622          *
1623          * Does the Win32 API documentation, or the NT Native API book,
1624          * suggest anything?
1625          */
1626         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1627                 tvb, offset, 4, mask);
1628         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1629                 tvb, offset, 4, mask);
1630         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1631                 tvb, offset, 4, mask);
1632         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1633                 tvb, offset, 4, mask);
1634         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1635                 tvb, offset, 4, mask);
1636         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1637                 tvb, offset, 4, mask);
1638         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1639                 tvb, offset, 4, mask);
1640         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1641                 tvb, offset, 4, mask);
1642         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1643                 tvb, offset, 4, mask);
1644         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1645                 tvb, offset, 4, mask);
1646         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1647                 tvb, offset, 4, mask);
1648         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1649                 tvb, offset, 4, mask);
1650         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1651                 tvb, offset, 4, mask);
1652         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1653                 tvb, offset, 4, mask);
1654         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1655                 tvb, offset, 4, mask);
1656
1657         offset += 4;
1658
1659         return offset;
1660 }
1661
1662 /* 3.11 */
1663 static int
1664 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1665 {
1666         guint32 mask;
1667
1668         mask = tvb_get_letohl(tvb, offset);
1669
1670         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, mask);
1671
1672         return offset;
1673 }
1674
1675 static int
1676 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1677 {
1678         guint8 mask;
1679         proto_item *item = NULL;
1680         proto_tree *tree = NULL;
1681
1682         mask = tvb_get_guint8(tvb, offset);
1683
1684         if(parent_tree){
1685                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1686                         "File Attributes: 0x%02x", mask);
1687                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1688         }
1689         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1690                 tvb, offset, 1, mask);
1691         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1692                 tvb, offset, 1, mask);
1693         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1694                 tvb, offset, 1, mask);
1695         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1696                 tvb, offset, 1, mask);
1697         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1698                 tvb, offset, 1, mask);
1699         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1700                 tvb, offset, 1, mask);
1701
1702         offset += 1;
1703
1704         return offset;
1705 }
1706
1707 static const true_false_string tfs_search_attribute_read_only = {
1708         "Include READ ONLY files in search results",
1709         "Do NOT include read only files in search results",
1710 };
1711 static const true_false_string tfs_search_attribute_hidden = {
1712         "Include HIDDEN files in search results",
1713         "Do NOT include hidden files in search results"
1714 };
1715 static const true_false_string tfs_search_attribute_system = {
1716         "Include SYSTEM files in search results",
1717         "Do NOT include system files in search results"
1718 };
1719 static const true_false_string tfs_search_attribute_volume = {
1720         "Include VOLUME IDs in search results",
1721         "Do NOT include volume IDs in search results"
1722 };
1723 static const true_false_string tfs_search_attribute_directory = {
1724         "Include DIRECTORIES in search results",
1725         "Do NOT include directories in search results"
1726 };
1727 static const true_false_string tfs_search_attribute_archive = {
1728         "Include ARCHIVE files in search results",
1729         "Do NOT include archive files in search results"
1730 };
1731
1732 static int
1733 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1734 {
1735         guint16 mask;
1736         proto_item *item = NULL;
1737         proto_tree *tree = NULL;
1738
1739         mask = tvb_get_letohs(tvb, offset);
1740
1741         if(parent_tree){
1742                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1743                         "Search Attributes: 0x%04x", mask);
1744                 tree = proto_item_add_subtree(item, ett_smb_search);
1745         }
1746
1747         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1748                 tvb, offset, 2, mask);
1749         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1750                 tvb, offset, 2, mask);
1751         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1752                 tvb, offset, 2, mask);
1753         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1754                 tvb, offset, 2, mask);
1755         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1756                 tvb, offset, 2, mask);
1757         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1758                 tvb, offset, 2, mask);
1759
1760         offset += 2;
1761         return offset;
1762 }
1763
1764 #if 0
1765 /*
1766  * XXX - this isn't used.
1767  * Is this used for anything?  NT Create AndX doesn't use it.
1768  * Is there some 16-bit attribute field with more bits than Read Only,
1769  * Hidden, System, Volume ID, Directory, and Archive?
1770  */
1771 static int
1772 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1773 {
1774         guint32 mask;
1775         proto_item *item = NULL;
1776         proto_tree *tree = NULL;
1777
1778         mask = tvb_get_letohl(tvb, offset);
1779
1780         if(parent_tree){
1781                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1782                         "File Attributes: 0x%08x", mask);
1783                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1784         }
1785         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1786                 tvb, offset, 2, mask);
1787         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1788                 tvb, offset, 2, mask);
1789         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1790                 tvb, offset, 2, mask);
1791         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1792                 tvb, offset, 2, mask);
1793         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1794                 tvb, offset, 2, mask);
1795         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1796                 tvb, offset, 2, mask);
1797         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1798                 tvb, offset, 2, mask);
1799         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1800                 tvb, offset, 2, mask);
1801         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1802                 tvb, offset, 2, mask);
1803         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1804                 tvb, offset, 2, mask);
1805         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1806                 tvb, offset, 2, mask);
1807         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1808                 tvb, offset, 2, mask);
1809         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1810                 tvb, offset, 2, mask);
1811         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1812                 tvb, offset, 2, mask);
1813         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1814                 tvb, offset, 2, mask);
1815
1816         offset += 2;
1817
1818         return offset;
1819 }
1820 #endif
1821
1822
1823 #define SERVER_CAP_RAW_MODE            0x00000001
1824 #define SERVER_CAP_MPX_MODE            0x00000002
1825 #define SERVER_CAP_UNICODE             0x00000004
1826 #define SERVER_CAP_LARGE_FILES         0x00000008
1827 #define SERVER_CAP_NT_SMBS             0x00000010
1828 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1829 #define SERVER_CAP_STATUS32            0x00000040
1830 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1831 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1832 #define SERVER_CAP_NT_FIND             0x00000200
1833 #define SERVER_CAP_DFS                 0x00001000
1834 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1835 #define SERVER_CAP_LARGE_READX         0x00004000
1836 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1837 #define SERVER_CAP_UNIX                0x00800000
1838 #define SERVER_CAP_RESERVED            0x02000000
1839 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1840 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1841 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1842 static const true_false_string tfs_server_cap_raw_mode = {
1843         "Read Raw and Write Raw are supported",
1844         "Read Raw and Write Raw are not supported"
1845 };
1846 static const true_false_string tfs_server_cap_mpx_mode = {
1847         "Read Mpx and Write Mpx are supported",
1848         "Read Mpx and Write Mpx are not supported"
1849 };
1850 static const true_false_string tfs_server_cap_unicode = {
1851         "Unicode strings are supported",
1852         "Unicode strings are not supported"
1853 };
1854 static const true_false_string tfs_server_cap_large_files = {
1855         "Large files are supported",
1856         "Large files are not supported",
1857 };
1858 static const true_false_string tfs_server_cap_nt_smbs = {
1859         "NT SMBs are supported",
1860         "NT SMBs are not supported"
1861 };
1862 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1863         "RPC remote APIs are supported",
1864         "RPC remote APIs are not supported"
1865 };
1866 static const true_false_string tfs_server_cap_nt_status = {
1867         "NT status codes are supported",
1868         "NT status codes are not supported"
1869 };
1870 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1871         "Level 2 oplocks are supported",
1872         "Level 2 oplocks are not supported"
1873 };
1874 static const true_false_string tfs_server_cap_lock_and_read = {
1875         "Lock and Read is supported",
1876         "Lock and Read is not supported"
1877 };
1878 static const true_false_string tfs_server_cap_nt_find = {
1879         "NT Find is supported",
1880         "NT Find is not supported"
1881 };
1882 static const true_false_string tfs_server_cap_dfs = {
1883         "Dfs is supported",
1884         "Dfs is not supported"
1885 };
1886 static const true_false_string tfs_server_cap_infolevel_passthru = {
1887         "NT information level request passthrough is supported",
1888         "NT information level request passthrough is not supported"
1889 };
1890 static const true_false_string tfs_server_cap_large_readx = {
1891         "Large Read andX is supported",
1892         "Large Read andX is not supported"
1893 };
1894 static const true_false_string tfs_server_cap_large_writex = {
1895         "Large Write andX is supported",
1896         "Large Write andX is not supported"
1897 };
1898 static const true_false_string tfs_server_cap_unix = {
1899         "UNIX extensions are supported",
1900         "UNIX extensions are not supported"
1901 };
1902 static const true_false_string tfs_server_cap_reserved = {
1903         "Reserved",
1904         "Reserved"
1905 };
1906 static const true_false_string tfs_server_cap_bulk_transfer = {
1907         "Bulk Read and Bulk Write are supported",
1908         "Bulk Read and Bulk Write are not supported"
1909 };
1910 static const true_false_string tfs_server_cap_compressed_data = {
1911         "Compressed data transfer is supported",
1912         "Compressed data transfer is not supported"
1913 };
1914 static const true_false_string tfs_server_cap_extended_security = {
1915         "Extended security exchanges are supported",
1916         "Extended security exchanges are not supported"
1917 };
1918 static int
1919 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1920 {
1921         guint32 mask;
1922         proto_item *item = NULL;
1923         proto_tree *tree = NULL;
1924
1925         mask = tvb_get_letohl(tvb, offset);
1926
1927         if(parent_tree){
1928                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1929                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1930         }
1931
1932         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1933                 tvb, offset, 4, mask);
1934         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1935                 tvb, offset, 4, mask);
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1941                 tvb, offset, 4, mask);
1942         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1943                 tvb, offset, 4, mask);
1944         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1945                 tvb, offset, 4, mask);
1946         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1947                 tvb, offset, 4, mask);
1948         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1949                 tvb, offset, 4, mask);
1950         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1951                 tvb, offset, 4, mask);
1952         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1953                 tvb, offset, 4, mask);
1954         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1955                 tvb, offset, 4, mask);
1956         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1957                 tvb, offset, 4, mask);
1958         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1959                 tvb, offset, 4, mask);
1960         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1961                 tvb, offset, 4, mask);
1962         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1963                 tvb, offset, 4, mask);
1964         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1965                 tvb, offset, 4, mask);
1966         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1967                 tvb, offset, 4, mask);
1968         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1969                 tvb, offset, 4, mask);
1970
1971         return mask;
1972 }
1973
1974 #define RAWMODE_READ   0x01
1975 #define RAWMODE_WRITE  0x02
1976 static const true_false_string tfs_rm_read = {
1977         "Read Raw is supported",
1978         "Read Raw is not supported"
1979 };
1980 static const true_false_string tfs_rm_write = {
1981         "Write Raw is supported",
1982         "Write Raw is not supported"
1983 };
1984
1985 static int
1986 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1987 {
1988         guint16 mask;
1989         proto_item *item = NULL;
1990         proto_tree *tree = NULL;
1991
1992         mask = tvb_get_letohs(tvb, offset);
1993
1994         if(parent_tree){
1995                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1996                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1997         }
1998
1999         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2000         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2001
2002         offset += 2;
2003
2004         return offset;
2005 }
2006
2007 #define SECURITY_MODE_MODE             0x01
2008 #define SECURITY_MODE_PASSWORD         0x02
2009 #define SECURITY_MODE_SIGNATURES       0x04
2010 #define SECURITY_MODE_SIG_REQUIRED     0x08
2011 static const true_false_string tfs_sm_mode = {
2012         "USER security mode",
2013         "SHARE security mode"
2014 };
2015 static const true_false_string tfs_sm_password = {
2016         "ENCRYPTED password. Use challenge/response",
2017         "PLAINTEXT password"
2018 };
2019 static const true_false_string tfs_sm_signatures = {
2020         "Security signatures ENABLED",
2021         "Security signatures NOT enabled"
2022 };
2023 static const true_false_string tfs_sm_sig_required = {
2024         "Security signatures REQUIRED",
2025         "Security signatures NOT required"
2026 };
2027
2028 static int
2029 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2030 {
2031         guint16 mask = 0;
2032         proto_item *item = NULL;
2033         proto_tree *tree = NULL;
2034
2035         switch(wc){
2036         case 13:
2037                 mask = tvb_get_letohs(tvb, offset);
2038                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2039                                 "Security Mode: 0x%04x", mask);
2040                 tree = proto_item_add_subtree(item, ett_smb_mode);
2041                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2042                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2043                 offset += 2;
2044                 break;
2045
2046         case 17:
2047                 mask = tvb_get_guint8(tvb, offset);
2048                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2049                                 "Security Mode: 0x%02x", mask);
2050                 tree = proto_item_add_subtree(item, ett_smb_mode);
2051                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2052                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2053                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2054                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2055                 offset += 1;
2056                 break;
2057         }
2058
2059         return offset;
2060 }
2061
2062 static int
2063 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2064 {
2065         proto_item *it = NULL;
2066         proto_tree *tr = NULL;
2067         guint16 bc;
2068         guint8 wc;
2069
2070         WORD_COUNT;
2071
2072         BYTE_COUNT;
2073
2074         if(tree){
2075                 tvb_ensure_bytes_exist(tvb, offset, bc);
2076                 it = proto_tree_add_text(tree, tvb, offset, bc,
2077                                 "Requested Dialects");
2078                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2079         }
2080
2081         while(bc){
2082                 int len;
2083                 const guint8 *str;
2084                 proto_item *dit = NULL;
2085                 proto_tree *dtr = NULL;
2086
2087                 /* XXX - what if this runs past bc? */
2088                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2089                 len = tvb_strsize(tvb, offset+1);
2090                 str = tvb_get_ptr(tvb, offset+1, len);
2091
2092                 if(tr){
2093                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2094                                         "Dialect: %s", str);
2095                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2096                 }
2097
2098                 /* Buffer Format */
2099                 CHECK_BYTE_COUNT(1);
2100                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2101                         TRUE);
2102                 COUNT_BYTES(1);
2103
2104                 /*Dialect Name */
2105                 CHECK_BYTE_COUNT(len);
2106                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2107                         len, str);
2108                 COUNT_BYTES(len);
2109         }
2110
2111         END_OF_SMB
2112
2113         return offset;
2114 }
2115
2116 static int
2117 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2118 {
2119         smb_info_t *si = pinfo->private_data;
2120         guint8 wc;
2121         guint16 dialect;
2122         const char *dn;
2123         int dn_len;
2124         guint16 bc;
2125         guint16 ekl=0;
2126         guint32 caps=0;
2127         gint16 tz;
2128
2129         DISSECTOR_ASSERT(si);
2130
2131         WORD_COUNT;
2132
2133         /* Dialect Index */
2134         dialect = tvb_get_letohs(tvb, offset);
2135         switch(wc){
2136         case 1:
2137                 if(dialect==0xffff){
2138                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2139                                 tvb, offset, 2, dialect,
2140                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2141                 } else {
2142                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2143                                 tvb, offset, 2, dialect);
2144                 }
2145                 break;
2146         case 13:
2147                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2148                         tvb, offset, 2, dialect,
2149                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2150                 break;
2151         case 17:
2152                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2153                         tvb, offset, 2, dialect,
2154                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2155                 break;
2156         default:
2157                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2158                 proto_tree_add_text(tree, tvb, offset, wc*2,
2159                         "Words for unknown response format");
2160                 offset += wc*2;
2161                 goto bytecount;
2162         }
2163         offset += 2;
2164
2165         switch(wc){
2166         case 13:
2167                 /* Security Mode */
2168                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2169
2170                 /* Maximum Transmit Buffer Size */
2171                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2172                         tvb, offset, 2, TRUE);
2173                 offset += 2;
2174
2175                 /* Maximum Multiplex Count */
2176                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2177                         tvb, offset, 2, TRUE);
2178                 offset += 2;
2179
2180                 /* Maximum Vcs Number */
2181                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2182                         tvb, offset, 2, TRUE);
2183                 offset += 2;
2184
2185                 /* raw mode */
2186                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2187
2188                 /* session key */
2189                 proto_tree_add_item(tree, hf_smb_session_key,
2190                         tvb, offset, 4, TRUE);
2191                 offset += 4;
2192
2193                 /* current time and date at server */
2194                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2195                     TRUE);
2196
2197                 /* time zone */
2198                 tz = tvb_get_letohs(tvb, offset);
2199                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2200                 offset += 2;
2201
2202                 /* encryption key length */
2203                 ekl = tvb_get_letohs(tvb, offset);
2204                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2205                 offset += 2;
2206
2207                 /* 2 reserved bytes */
2208                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2209                 offset += 2;
2210
2211                 break;
2212
2213         case 17:
2214                 /* Security Mode */
2215                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2216
2217                 /* Maximum Multiplex Count */
2218                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2219                         tvb, offset, 2, TRUE);
2220                 offset += 2;
2221
2222                 /* Maximum Vcs Number */
2223                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2224                         tvb, offset, 2, TRUE);
2225                 offset += 2;
2226
2227                 /* Maximum Transmit Buffer Size */
2228                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2229                         tvb, offset, 4, TRUE);
2230                 offset += 4;
2231
2232                 /* maximum raw buffer size */
2233                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2234                         tvb, offset, 4, TRUE);
2235                 offset += 4;
2236
2237                 /* session key */
2238                 proto_tree_add_item(tree, hf_smb_session_key,
2239                         tvb, offset, 4, TRUE);
2240                 offset += 4;
2241
2242                 /* server capabilities */
2243                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2244                 offset += 4;
2245
2246                 /* system time */
2247                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2248                                 hf_smb_system_time);
2249
2250                 /* time zone */
2251                 tz = tvb_get_letohs(tvb, offset);
2252                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2253                         tvb, offset, 2, tz,
2254                         "Server Time Zone: %d min from UTC", tz);
2255                 offset += 2;
2256
2257                 /* encryption key length */
2258                 ekl = tvb_get_guint8(tvb, offset);
2259                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2260                         tvb, offset, 1, ekl);
2261                 offset += 1;
2262
2263                 break;
2264         }
2265
2266         BYTE_COUNT;
2267
2268         switch(wc){
2269         case 13:
2270                 /* challenge/response encryption key */
2271                 if(ekl){
2272                         CHECK_BYTE_COUNT(ekl);
2273                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2274                         COUNT_BYTES(ekl);
2275                 }
2276
2277                 /*
2278                  * Primary domain.
2279                  *
2280                  * XXX - not present if negotiated dialect isn't
2281                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2282                  * have to see the request, or assume what dialect strings
2283                  * were sent, to determine that.
2284                  *
2285                  * Is this something other than a primary domain if the
2286                  * negotiated dialect is Windows for Workgroups 3.1a?
2287                  * It appears to be 8 bytes of binary data in at least
2288                  * one capture - is that an encryption key or something
2289                  * such as that?
2290                  */
2291                 dn = get_unicode_or_ascii_string(tvb, &offset,
2292                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2293                 if (dn == NULL)
2294                         goto endofcommand;
2295                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2296                         offset, dn_len,dn);
2297                 COUNT_BYTES(dn_len);
2298                 break;
2299
2300         case 17:
2301                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2302                         /* challenge/response encryption key */
2303                         /* XXX - is this aligned on an even boundary? */
2304                         if(ekl){
2305                                 CHECK_BYTE_COUNT(ekl);
2306                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2307                                         tvb, offset, ekl, TRUE);
2308                                 COUNT_BYTES(ekl);
2309                         }
2310
2311                         /* domain */
2312                         /* this string is special, unicode is flagged in caps */
2313                         /* This string is NOT padded to be 16bit aligned.
2314                            (seen in actual capture)
2315                            XXX - I've seen a capture where it appears to be
2316                            so aligned, but I've also seen captures where
2317                            it is.  The captures where it appeared to be
2318                            aligned may have been from buggy servers. */
2319                         /* However, don't get rid of existing setting */
2320                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2321                           si->unicode;
2322
2323                         dn = get_unicode_or_ascii_string(tvb,
2324                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2325                                 &bc);
2326                         if (dn == NULL)
2327                                 goto endofcommand;
2328                         proto_tree_add_string(tree, hf_smb_primary_domain,
2329                                 tvb, offset, dn_len, dn);
2330                         COUNT_BYTES(dn_len);
2331
2332                         /* server name, seen in w2k pro capture */
2333                         dn = get_unicode_or_ascii_string(tvb,
2334                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2335                                 &bc);
2336                         if (dn == NULL)
2337                                 goto endofcommand;
2338                         proto_tree_add_string(tree, hf_smb_server,
2339                                 tvb, offset, dn_len, dn);
2340                         COUNT_BYTES(dn_len);
2341
2342                 } else {
2343                         proto_item *blob_item;
2344                         guint16 sbloblen;
2345
2346                         /* guid */
2347                         /* XXX - show it in the standard Microsoft format
2348                            for GUIDs? */
2349                         CHECK_BYTE_COUNT(16);
2350                         proto_tree_add_item(tree, hf_smb_server_guid,
2351                                 tvb, offset, 16, TRUE);
2352                         COUNT_BYTES(16);
2353
2354                         /* security blob */
2355                         /* If it runs past the end of the captured data, don't
2356                          * try to put all of it into the protocol tree as the
2357                          * raw security blob; we might get an exception on 
2358                          * short frames and then we will not see anything at all
2359                          * of the security blob.
2360                          */
2361                         sbloblen=bc;
2362                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2363                                 sbloblen=tvb_length_remaining(tvb,offset);
2364                         }
2365                         blob_item = proto_tree_add_item(
2366                                 tree, hf_smb_security_blob,
2367                                 tvb, offset, sbloblen, TRUE);
2368
2369                         /* 
2370                          * If Extended security and BCC == 16, then raw 
2371                          * NTLMSSP is in use. We need to save this info
2372                          */
2373  
2374                         if(bc){
2375                                 tvbuff_t *gssapi_tvb;
2376                                 proto_tree *gssapi_tree;
2377
2378                                 gssapi_tree = proto_item_add_subtree(
2379                                         blob_item, ett_smb_secblob);
2380
2381                                 /*
2382                                  * Set the reported length of this to
2383                                  * the reported length of the blob,
2384                                  * rather than the amount of data
2385                                  * available from the blob, so that
2386                                  * we'll throw the right exception if
2387                                  * it's too short.
2388                                  */
2389                                 gssapi_tvb = tvb_new_subset(
2390                                         tvb, offset, sbloblen, bc);
2391
2392                                 call_dissector(
2393                                         gssapi_handle, gssapi_tvb, pinfo,
2394                                         gssapi_tree);
2395
2396                                 if (si->ct)
2397                                   si->ct->raw_ntlmssp = 0;
2398
2399                                 COUNT_BYTES(bc);
2400                         }
2401                         else { 
2402
2403                           /*
2404                            * There is no blob. We just have to make sure
2405                            * that subsequent routines know to call the 
2406                            * right things ...
2407                            */
2408
2409                           if (si->ct)
2410                             si->ct->raw_ntlmssp = 1;
2411
2412                         }
2413                 }
2414                 break;
2415         }
2416
2417         END_OF_SMB
2418
2419         return offset;
2420 }
2421
2422
2423 static int
2424 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2425 {
2426         smb_info_t *si = pinfo->private_data;
2427         int dn_len;
2428         const char *dn;
2429         guint8 wc;
2430         guint16 bc;
2431
2432         DISSECTOR_ASSERT(si);
2433
2434         WORD_COUNT;
2435
2436         BYTE_COUNT;
2437
2438         /* buffer format */
2439         CHECK_BYTE_COUNT(1);
2440         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2441         COUNT_BYTES(1);
2442
2443         /* dir name */
2444         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2445                 FALSE, FALSE, &bc);
2446         if (dn == NULL)
2447                 goto endofcommand;
2448         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2449                 dn);
2450         COUNT_BYTES(dn_len);
2451
2452         if (check_col(pinfo->cinfo, COL_INFO)) {
2453                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2454                     format_text(dn, strlen(dn)));
2455         }
2456
2457         END_OF_SMB
2458
2459         return offset;
2460 }
2461
2462 static int
2463 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2464 {
2465         guint8 wc;
2466         guint16 bc;
2467
2468         WORD_COUNT;
2469
2470         BYTE_COUNT;
2471
2472         END_OF_SMB
2473
2474         return offset;
2475 }
2476
2477 static int
2478 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2479 {
2480         guint16 ec, bc;
2481         guint8 wc;
2482
2483         WORD_COUNT;
2484
2485         /* echo count */
2486         ec = tvb_get_letohs(tvb, offset);
2487         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2488         offset += 2;
2489
2490         BYTE_COUNT;
2491
2492         if (bc != 0) {
2493                 /* echo data */
2494                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2495                 COUNT_BYTES(bc);
2496         }
2497
2498         END_OF_SMB
2499
2500         return offset;
2501 }
2502
2503 static int
2504 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2505 {
2506         guint16 bc;
2507         guint8 wc;
2508
2509         WORD_COUNT;
2510
2511         /* echo sequence number */
2512         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2513         offset += 2;
2514
2515         BYTE_COUNT;
2516
2517         if (bc != 0) {
2518                 /* echo data */
2519                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2520                 COUNT_BYTES(bc);
2521         }
2522
2523         END_OF_SMB
2524
2525         return offset;
2526 }
2527
2528 static int
2529 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2530 {
2531         smb_info_t *si = pinfo->private_data;
2532         int an_len, pwlen;
2533         const char *an;
2534         guint8 wc;
2535         guint16 bc;
2536
2537         DISSECTOR_ASSERT(si);
2538
2539         WORD_COUNT;
2540
2541         BYTE_COUNT;
2542
2543         /* buffer format */
2544         CHECK_BYTE_COUNT(1);
2545         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2546         COUNT_BYTES(1);
2547
2548         /* Path */
2549         an = get_unicode_or_ascii_string(tvb, &offset,
2550                 si->unicode, &an_len, FALSE, FALSE, &bc);
2551         if (an == NULL)
2552                 goto endofcommand;
2553         proto_tree_add_string(tree, hf_smb_path, tvb,
2554                 offset, an_len, an);
2555         COUNT_BYTES(an_len);
2556
2557         if (check_col(pinfo->cinfo, COL_INFO)) {
2558                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2559                     format_text(an, strlen(an)));
2560         }
2561
2562         /* buffer format */
2563         CHECK_BYTE_COUNT(1);
2564         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2565         COUNT_BYTES(1);
2566
2567         /* password, ANSI */
2568         /* XXX - what if this runs past bc? */
2569         pwlen = tvb_strsize(tvb, offset);
2570         CHECK_BYTE_COUNT(pwlen);
2571         proto_tree_add_item(tree, hf_smb_password,
2572                 tvb, offset, pwlen, TRUE);
2573         COUNT_BYTES(pwlen);
2574
2575         /* buffer format */
2576         CHECK_BYTE_COUNT(1);
2577         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2578         COUNT_BYTES(1);
2579
2580         /* Service */
2581         /*
2582          * XXX - the SNIA CIFS spec "Strings that are never passed in
2583          * Unicode are: ... The service name string in the
2584          * Tree_Connect_AndX SMB".  Is that claim false?
2585          */
2586         an = get_unicode_or_ascii_string(tvb, &offset,
2587                 si->unicode, &an_len, FALSE, FALSE, &bc);
2588         if (an == NULL)
2589                 goto endofcommand;
2590         proto_tree_add_string(tree, hf_smb_service, tvb,
2591                 offset, an_len, an);
2592         COUNT_BYTES(an_len);
2593
2594         END_OF_SMB
2595
2596         return offset;
2597 }
2598
2599 static int
2600 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2601 {
2602         proto_item *item, *subitem;
2603         proto_tree *tree;
2604         smb_uid_t *smb_uid=NULL;
2605
2606         item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2607         tree=proto_item_add_subtree(item, ett_smb_uid);
2608
2609         smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
2610         if(smb_uid){
2611                 if(smb_uid->domain && smb_uid->account)
2612                         proto_item_append_text(item, "  (");
2613                 if(smb_uid->domain){
2614                         proto_item_append_text(item, "%s", smb_uid->domain);
2615                         subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2616                         PROTO_ITEM_SET_GENERATED(subitem);
2617                 }
2618                 if(smb_uid->account){
2619                         proto_item_append_text(item, "\\%s", smb_uid->account);
2620                         subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2621                         PROTO_ITEM_SET_GENERATED(subitem);
2622                 }
2623                 if(smb_uid->domain && smb_uid->account)
2624                         proto_item_append_text(item, ")");
2625                 if(smb_uid->logged_in>0){
2626                         subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2627                         PROTO_ITEM_SET_GENERATED(subitem);
2628                 }
2629                 if(smb_uid->logged_out>0){
2630                         subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2631                         PROTO_ITEM_SET_GENERATED(subitem);
2632                 }
2633         }
2634         offset += 2;
2635
2636         return offset;
2637 }
2638
2639 static int
2640 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
2641 {
2642         smb_info_t *si = pinfo->private_data;
2643         proto_item *it;
2644         proto_tree *tr;
2645         smb_tid_info_t *tid_info=NULL;
2646
2647         DISSECTOR_ASSERT(si);
2648
2649         /* tid */
2650         it=proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2651         tr=proto_item_add_subtree(it, ett_smb_tid);
2652         offset += 2;
2653
2654         if((!pinfo->fd->flags.visited) && is_created){
2655                 tid_info=se_alloc(sizeof(smb_tid_info_t));
2656                 tid_info->opened_in=pinfo->fd->num;
2657                 tid_info->closed_in=0;
2658                 tid_info->type=SMB_FID_TYPE_UNKNOWN;
2659                 if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
2660                         tid_info->filename=si->sip->extra_info;
2661                 } else {
2662                         tid_info->filename=NULL;
2663                 }
2664                 se_tree_insert32(si->ct->tid_tree, tid, tid_info);
2665         }
2666
2667         if(!tid_info){
2668                 tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
2669         }
2670         if(!tid_info){
2671                 return offset;
2672         }
2673
2674         if((!pinfo->fd->flags.visited) && is_closed){
2675                 tid_info->closed_in=pinfo->fd->num;
2676         }
2677
2678         if(tid_info->opened_in){
2679                 if(tid_info->filename){
2680                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2681
2682                         it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2683                         PROTO_ITEM_SET_GENERATED(it);
2684                 }
2685
2686                 it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2687                 PROTO_ITEM_SET_GENERATED(it);
2688         }               
2689         if(tid_info->closed_in){
2690                 it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2691                 PROTO_ITEM_SET_GENERATED(it);
2692         }               
2693
2694
2695         return offset;
2696 }
2697
2698 static int
2699 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2700 {
2701         guint8 wc;
2702         guint16 bc;
2703
2704         WORD_COUNT;
2705
2706         /* Maximum Buffer Size */
2707         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2708         offset += 2;
2709
2710         /* tid */
2711         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE);
2712
2713         BYTE_COUNT;
2714
2715         END_OF_SMB
2716
2717         return offset;
2718 }
2719
2720
2721 static const true_false_string tfs_of_create = {
2722         "Create file if it does not exist",
2723         "Fail if file does not exist"
2724 };
2725 static const value_string of_open[] = {
2726         { 0,            "Fail if file exists"},
2727         { 1,            "Open file if it exists"},
2728         { 2,            "Truncate file if it exists"},
2729         {0, NULL}
2730 };
2731 static int
2732 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2733 {
2734         guint16 mask;
2735         proto_item *item = NULL;
2736         proto_tree *tree = NULL;
2737
2738         mask = tvb_get_letohs(tvb, offset);
2739
2740         if(parent_tree){
2741                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2742                         "Open Function: 0x%04x", mask);
2743                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2744         }
2745
2746         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2747                 tvb, offset, 2, mask);
2748         proto_tree_add_uint(tree, hf_smb_open_function_open,
2749                 tvb, offset, 2, mask);
2750
2751         offset += 2;
2752
2753         return offset;
2754 }
2755
2756
2757 static const true_false_string tfs_mf_file = {
2758         "Target must be a file",
2759         "Target needn't be a file"
2760 };
2761 static const true_false_string tfs_mf_dir = {
2762         "Target must be a directory",
2763         "Target needn't be a directory"
2764 };
2765 static const true_false_string tfs_mf_verify = {
2766         "MUST verify all writes",
2767         "Don't have to verify writes"
2768 };
2769 static int
2770 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2771 {
2772         guint16 mask;
2773         proto_item *item = NULL;
2774         proto_tree *tree = NULL;
2775
2776         mask = tvb_get_letohs(tvb, offset);
2777
2778         if(parent_tree){
2779                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2780                         "Flags: 0x%04x", mask);
2781                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2782         }
2783
2784         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2785                 tvb, offset, 2, mask);
2786         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2787                 tvb, offset, 2, mask);
2788         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2789                 tvb, offset, 2, mask);
2790
2791         offset += 2;
2792
2793         return offset;
2794 }
2795
2796 static const true_false_string tfs_cf_mode = {
2797         "ASCII",
2798         "Binary"
2799 };
2800 static const true_false_string tfs_cf_tree_copy = {
2801         "Copy is a tree copy",
2802         "Copy is a file copy"
2803 };
2804 static const true_false_string tfs_cf_ea_action = {
2805         "Fail copy",
2806         "Discard EAs"
2807 };
2808 static int
2809 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2810 {
2811         guint16 mask;
2812         proto_item *item = NULL;
2813         proto_tree *tree = NULL;
2814
2815         mask = tvb_get_letohs(tvb, offset);
2816
2817         if(parent_tree){
2818                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2819                         "Flags: 0x%04x", mask);
2820                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2821         }
2822
2823         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2824                 tvb, offset, 2, mask);
2825         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2826                 tvb, offset, 2, mask);
2827         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2828                 tvb, offset, 2, mask);
2829         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2830                 tvb, offset, 2, mask);
2831         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2832                 tvb, offset, 2, mask);
2833         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2834                 tvb, offset, 2, mask);
2835         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2836                 tvb, offset, 2, mask);
2837
2838         offset += 2;
2839
2840         return offset;
2841 }
2842
2843 static int
2844 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2845 {
2846         smb_info_t *si = pinfo->private_data;
2847         int fn_len;
2848         guint16 tid;
2849         guint16 bc;
2850         guint8 wc;
2851         const char *fn;
2852
2853         DISSECTOR_ASSERT(si);
2854
2855         WORD_COUNT;
2856
2857         /* tid */
2858         tid = tvb_get_letohs(tvb, offset);
2859         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2860
2861         /* open function */
2862         offset = dissect_open_function(tvb, tree, offset);
2863
2864         /* move flags */
2865         offset = dissect_move_flags(tvb, tree, offset);
2866
2867         BYTE_COUNT;
2868
2869         /* buffer format */
2870         CHECK_BYTE_COUNT(1);
2871         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2872         COUNT_BYTES(1);
2873
2874         /* file name */
2875         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2876                 FALSE, FALSE, &bc);
2877         if (fn == NULL)
2878                 goto endofcommand;
2879         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2880                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
2881         COUNT_BYTES(fn_len);
2882
2883         if (check_col(pinfo->cinfo, COL_INFO)) {
2884                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
2885                     format_text(fn, strlen(fn)));
2886         }
2887
2888         /* buffer format */
2889         CHECK_BYTE_COUNT(1);
2890         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2891         COUNT_BYTES(1);
2892
2893         /* file name */
2894         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2895                 FALSE, FALSE, &bc);
2896         if (fn == NULL)
2897                 goto endofcommand;
2898         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2899                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
2900         COUNT_BYTES(fn_len);
2901
2902         if (check_col(pinfo->cinfo, COL_INFO)) {
2903                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
2904                     format_text(fn, strlen(fn)));
2905         }
2906
2907         END_OF_SMB
2908
2909         return offset;
2910 }
2911
2912 static int
2913 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2914 {
2915         smb_info_t *si = pinfo->private_data;
2916         int fn_len;
2917         guint16 tid;
2918         guint16 bc;
2919         guint8 wc;
2920         const char *fn;
2921
2922         DISSECTOR_ASSERT(si);
2923
2924         WORD_COUNT;
2925
2926         /* tid */
2927         tid = tvb_get_letohs(tvb, offset);
2928         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2929
2930         /* open function */
2931         offset = dissect_open_function(tvb, tree, offset);
2932
2933         /* copy flags */
2934         offset = dissect_copy_flags(tvb, tree, offset);
2935
2936         BYTE_COUNT;
2937
2938         /* buffer format */
2939         CHECK_BYTE_COUNT(1);
2940         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2941         COUNT_BYTES(1);
2942
2943         /* file name */
2944         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2945                 FALSE, FALSE, &bc);
2946         if (fn == NULL)
2947                 goto endofcommand;
2948         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2949                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
2950         COUNT_BYTES(fn_len);
2951
2952         if (check_col(pinfo->cinfo, COL_INFO)) {
2953                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
2954                     format_text(fn, strlen(fn)));
2955         }
2956
2957         /* buffer format */
2958         CHECK_BYTE_COUNT(1);
2959         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2960         COUNT_BYTES(1);
2961
2962         /* file name */
2963         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2964                 FALSE, FALSE, &bc);
2965         if (fn == NULL)
2966                 goto endofcommand;
2967         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2968                 fn_len, fn, "Destination File Name: %s",
2969                 format_text(fn, strlen(fn)));
2970         COUNT_BYTES(fn_len);
2971
2972         if (check_col(pinfo->cinfo, COL_INFO)) {
2973                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
2974         }
2975
2976         END_OF_SMB
2977
2978         return offset;
2979 }
2980
2981 static int
2982 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2983 {
2984         smb_info_t *si = pinfo->private_data;
2985         int fn_len;
2986         const char *fn;
2987         guint8 wc;
2988         guint16 bc;
2989
2990         DISSECTOR_ASSERT(si);
2991
2992         WORD_COUNT;
2993
2994         /* # of files moved */
2995         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2996         offset += 2;
2997
2998         BYTE_COUNT;
2999
3000         /* buffer format */
3001         CHECK_BYTE_COUNT(1);
3002         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3003         COUNT_BYTES(1);
3004
3005         /* file name */
3006         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3007                 FALSE, FALSE, &bc);
3008         if (fn == NULL)
3009                 goto endofcommand;
3010         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3011                 fn);
3012         COUNT_BYTES(fn_len);
3013
3014         END_OF_SMB
3015
3016         return offset;
3017 }
3018
3019 static int
3020 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3021 {
3022         smb_info_t *si = pinfo->private_data;
3023         int fn_len;
3024         const char *fn;
3025         guint8 wc;
3026         guint16 bc;
3027
3028         DISSECTOR_ASSERT(si);
3029
3030         WORD_COUNT;
3031
3032         /* desired access */
3033         offset = dissect_access(tvb, tree, offset, "Desired");
3034
3035         /* Search Attributes */
3036         offset = dissect_search_attributes(tvb, tree, offset);
3037
3038         BYTE_COUNT;
3039
3040         /* buffer format */
3041         CHECK_BYTE_COUNT(1);
3042         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3043         COUNT_BYTES(1);
3044
3045         /* file name */
3046         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3047                 FALSE, FALSE, &bc);
3048         if (fn == NULL)
3049                 goto endofcommand;
3050         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3051                 fn);
3052         COUNT_BYTES(fn_len);
3053
3054         if (check_col(pinfo->cinfo, COL_INFO)) {
3055                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3056                     format_text(fn, strlen(fn)));
3057         }
3058
3059         END_OF_SMB
3060
3061         return offset;
3062 }
3063
3064
3065
3066 static int
3067 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset, guint32 mask)
3068 {
3069         proto_item *item = NULL;
3070         proto_tree *tree = NULL;
3071
3072         if(parent_tree){
3073                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, 4, mask);
3074
3075                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3076         }
3077
3078         /*
3079          * XXX - it's 0x00000016 in at least one capture, but
3080          * Network Monitor doesn't say what the 0x00000010 bit is.
3081          * Does the Win32 API documentation, or NT Native API book,
3082          * suggest anything?
3083          *
3084          * That is the extended response desired bit ... RJS, from Samba
3085          * Well, maybe. Samba thinks it is, and uses it to encode
3086          * OpLock granted as the high order bit of the Action field
3087          * in the response. However, Windows does not do that. Or at least
3088          * Win2K doesn't.
3089          */
3090         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3091                                tvb, offset, 4, mask);
3092         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3093                 tvb, offset, 4, mask);
3094         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3095                 tvb, offset, 4, mask);
3096         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3097                 tvb, offset, 4, mask);
3098
3099         offset += 4;
3100
3101         return offset;
3102 }
3103
3104 /* FIXME: need to call dissect_nt_access_mask() instead */
3105 static int
3106 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset, guint32 mask)
3107 {
3108         proto_item *item = NULL;
3109         proto_tree *tree = NULL;
3110
3111         if(parent_tree){
3112                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, 4, mask);
3113                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3114         }
3115
3116         /*
3117          * Some of these bits come from
3118          *
3119          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3120          *
3121          * and others come from the section on ZwOpenFile in "Windows(R)
3122          * NT(R)/2000 Native API Reference".
3123          */
3124         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3125                 tvb, offset, 4, mask);
3126         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3127                 tvb, offset, 4, mask);
3128         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3129                 tvb, offset, 4, mask);
3130         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3131                 tvb, offset, 4, mask);
3132         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3133                 tvb, offset, 4, mask);
3134         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3135                 tvb, offset, 4, mask);
3136         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3137                 tvb, offset, 4, mask);
3138         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3139                 tvb, offset, 4, mask);
3140         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3141                 tvb, offset, 4, mask);
3142         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3143                 tvb, offset, 4, mask);
3144         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3145                 tvb, offset, 4, mask);
3146         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3147                 tvb, offset, 4, mask);
3148         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3149                 tvb, offset, 4, mask);
3150         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3151                 tvb, offset, 4, mask);
3152         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3153                 tvb, offset, 4, mask);
3154         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3155                 tvb, offset, 4, mask);
3156         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3157                 tvb, offset, 4, mask);
3158         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3159                 tvb, offset, 4, mask);
3160         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3161                 tvb, offset, 4, mask);
3162         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3163                 tvb, offset, 4, mask);
3164
3165         offset += 4;
3166
3167         return offset;
3168 }
3169
3170 int
3171 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3172 {
3173         guint32 mask;
3174
3175         mask = tvb_get_letohl(tvb, offset);
3176
3177         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, mask);
3178
3179         return offset;
3180 }
3181
3182
3183 #define SHARE_ACCESS_DELETE     0x00000004
3184 #define SHARE_ACCESS_WRITE      0x00000002
3185 #define SHARE_ACCESS_READ       0x00000001
3186
3187 static int
3188 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset, guint32 mask)
3189 {
3190         proto_item *item = NULL;
3191         proto_tree *tree = NULL;
3192
3193         if(parent_tree){
3194                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, 4, mask);
3195                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3196         }
3197
3198         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3199                 tvb, offset, 4, mask);
3200         if(mask&SHARE_ACCESS_DELETE){
3201                 proto_item_append_text(item, " SHARE_DELETE");
3202         }
3203
3204         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3205                 tvb, offset, 4, mask);
3206         if(mask&SHARE_ACCESS_WRITE){
3207                 proto_item_append_text(item, " SHARE_WRITE");
3208         }
3209
3210         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3211                 tvb, offset, 4, mask);
3212         if(mask&SHARE_ACCESS_READ){
3213                 proto_item_append_text(item, " SHARE_READ");
3214         }
3215
3216         offset += 4;
3217
3218         return offset;
3219 }
3220
3221 int
3222 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3223 {
3224         guint32 mask;
3225
3226         mask = tvb_get_letohl(tvb, offset);
3227
3228         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, mask);
3229
3230         return offset;
3231 }
3232
3233
3234 static int
3235 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset, guint32 mask)
3236 {
3237         proto_item *item = NULL;
3238         proto_tree *tree = NULL;
3239
3240         if(parent_tree){
3241                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, 4, mask);
3242                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3243         }
3244
3245         /*
3246          * From
3247          *
3248          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3249          */
3250         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3251                 tvb, offset, 4, mask);
3252         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3253                 tvb, offset, 4, mask);
3254         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3255                 tvb, offset, 4, mask);
3256         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3257                 tvb, offset, 4, mask);
3258         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3259                 tvb, offset, 4, mask);
3260         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3261                 tvb, offset, 4, mask);
3262         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3263                 tvb, offset, 4, mask);
3264         proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3265                 tvb, offset, 4, mask);
3266         proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3267                 tvb, offset, 4, mask);
3268         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3269                 tvb, offset, 4, mask);
3270         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3271                 tvb, offset, 4, mask);
3272         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3273                 tvb, offset, 4, mask);
3274         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3275                 tvb, offset, 4, mask);
3276         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3277                 tvb, offset, 4, mask);
3278         proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3279                 tvb, offset, 4, mask);
3280         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3281                 tvb, offset, 4, mask);
3282         proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3283                 tvb, offset, 4, mask);
3284         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3285                 tvb, offset, 4, mask);
3286         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3287                 tvb, offset, 4, mask);
3288         proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3289                 tvb, offset, 4, mask);
3290
3291         offset += 4;
3292
3293         return offset;
3294 }
3295
3296 int
3297 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3298 {
3299         guint32 mask;
3300
3301         mask = tvb_get_letohl(tvb, offset);
3302
3303         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, mask);
3304
3305         return offset;
3306 }
3307
3308
3309 /* fids are scoped by tcp session */
3310 smb_fid_info_t *
3311 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3312     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
3313 {
3314         smb_info_t *si = pinfo->private_data;
3315         smb_saved_info_t *sip = si->sip;
3316         proto_item *it;
3317         proto_tree *tr;
3318         smb_fid_info_t *fid_info=NULL;
3319
3320         DISSECTOR_ASSERT(si);
3321
3322         it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3323         if(is_generated){
3324                 PROTO_ITEM_SET_GENERATED(it);
3325         }
3326         tr=proto_item_add_subtree(it, ett_smb_fid);
3327         if (check_col(pinfo->cinfo, COL_INFO))
3328                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3329
3330         if((!pinfo->fd->flags.visited) && is_created){
3331                 fid_info=se_alloc(sizeof(smb_fid_info_t));
3332                 fid_info->opened_in=pinfo->fd->num;
3333                 fid_info->closed_in=0;
3334                 fid_info->type=SMB_FID_TYPE_UNKNOWN;
3335                 if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
3336                         fid_info->fsi=si->sip->extra_info;
3337                 } else {
3338                         fid_info->fsi=NULL;
3339                 }
3340
3341                 se_tree_insert32(si->ct->fid_tree, fid, fid_info);
3342         }
3343
3344         if(!fid_info){
3345                 fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
3346         }
3347         if(!fid_info){
3348                 return NULL;
3349         }
3350
3351         /* Store the fid in the transaction structure and remember if
3352            it was in the request or in the reply we saw it 
3353          */
3354         if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3355                 sip->fid=fid;
3356                 if(si->request){
3357                         sip->fid_seen_in_request=TRUE;
3358                 } else {
3359                         sip->fid_seen_in_request=FALSE;
3360                 }
3361         }
3362
3363         if((!pinfo->fd->flags.visited) && is_closed){
3364                 fid_info->closed_in=pinfo->fd->num;
3365         }
3366
3367         if(fid_info->opened_in){
3368                 it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3369                 PROTO_ITEM_SET_GENERATED(it);
3370         }
3371
3372         if(fid_info->closed_in){
3373                 it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3374                 PROTO_ITEM_SET_GENERATED(it);
3375         }
3376                 
3377
3378         if(fid_info->opened_in){
3379                 if(fid_info->fsi && fid_info->fsi->filename){
3380                         it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3381                         PROTO_ITEM_SET_GENERATED(it);
3382                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3383                         dissect_nt_create_bits(tvb, tr, 0, fid_info->fsi->create_flags);
3384                         dissect_smb_access_mask_bits(tvb, tr, 0,fid_info->fsi->access_mask);
3385                         dissect_file_ext_attr_bits(tvb, tr, 0, fid_info->fsi->file_attributes);
3386                         dissect_nt_share_access_bits(tvb, tr, 0, fid_info->fsi->share_access);
3387                         dissect_nt_create_options_bits(tvb, tr, 0, fid_info->fsi->create_options);
3388                 }
3389         }               
3390
3391         return fid_info;
3392 }
3393
3394 static int
3395 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3396 {
3397         guint8 wc;
3398         guint16 bc;
3399         guint16 fid;
3400
3401         WORD_COUNT;
3402
3403         /* fid */
3404         fid = tvb_get_letohs(tvb, offset);
3405         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3406         offset += 2;
3407
3408         /* File Attributes */
3409         offset = dissect_file_attributes(tvb, tree, offset, 2);
3410
3411         /* last write time */
3412         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3413
3414         /* File Size */
3415         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3416         offset += 4;
3417
3418         /* granted access */
3419         offset = dissect_access(tvb, tree, offset, "Granted");
3420
3421         BYTE_COUNT;
3422
3423         END_OF_SMB
3424
3425         return offset;
3426 }
3427
3428 static int
3429 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3430 {
3431         guint8 wc;
3432         guint16 bc;
3433         guint16 fid;
3434
3435         WORD_COUNT;
3436
3437         /* fid */
3438         fid = tvb_get_letohs(tvb, offset);
3439         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3440         offset += 2;
3441
3442         BYTE_COUNT;
3443
3444         END_OF_SMB
3445
3446         return offset;
3447 }
3448
3449 static int
3450 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3451 {
3452         guint8 wc;
3453         guint16 bc;
3454         guint16 fid;
3455
3456         WORD_COUNT;
3457
3458         /* fid */
3459         fid = tvb_get_letohs(tvb, offset);
3460         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3461         offset += 2;
3462
3463         BYTE_COUNT;
3464
3465         END_OF_SMB
3466
3467         return offset;
3468 }
3469
3470 static int
3471 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3472 {
3473         guint8 wc;
3474         guint16 bc;
3475         guint16 fid;
3476
3477         WORD_COUNT;
3478
3479         /* fid */
3480         fid = tvb_get_letohs(tvb, offset);
3481         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3482         offset += 2;
3483
3484         BYTE_COUNT;
3485
3486         END_OF_SMB
3487
3488         return offset;
3489 }
3490
3491 static int
3492 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3493 {
3494         guint8 wc;
3495         guint16 bc;
3496         guint16 fid;
3497
3498         WORD_COUNT;
3499
3500         /* fid */
3501         fid = tvb_get_letohs(tvb, offset);
3502         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3503         offset += 2;
3504
3505         BYTE_COUNT;
3506
3507         END_OF_SMB
3508
3509         return offset;
3510 }
3511
3512 static int
3513 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3514 {
3515         guint8 wc;
3516         guint16 bc;
3517         guint16 fid;
3518
3519         WORD_COUNT;
3520
3521         /* fid */
3522         fid = tvb_get_letohs(tvb, offset);
3523         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3524         offset += 2;
3525
3526         BYTE_COUNT;
3527
3528         END_OF_SMB
3529
3530         return offset;
3531 }
3532
3533 static int
3534 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3535 {
3536         guint8 wc;
3537         guint16 bc;
3538         guint16 fid;
3539
3540         WORD_COUNT;
3541
3542         /* fid */
3543         fid = tvb_get_letohs(tvb, offset);
3544         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3545         offset += 2;
3546
3547         BYTE_COUNT;
3548
3549         END_OF_SMB
3550
3551         return offset;
3552 }
3553
3554 static int
3555 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3556 {
3557         smb_info_t *si = pinfo->private_data;
3558         int fn_len;
3559         const char *fn;
3560         guint8 wc;
3561         guint16 bc;
3562
3563         DISSECTOR_ASSERT(si);
3564
3565         WORD_COUNT;
3566
3567         /* file attributes */
3568         offset = dissect_file_attributes(tvb, tree, offset, 2);
3569
3570         /* creation time */
3571         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3572
3573         BYTE_COUNT;
3574
3575         /* buffer format */
3576         CHECK_BYTE_COUNT(1);
3577         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3578         COUNT_BYTES(1);
3579
3580         /* File Name */
3581         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3582                 FALSE, FALSE, &bc);
3583         if (fn == NULL)
3584                 goto endofcommand;
3585         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3586                 fn);
3587         COUNT_BYTES(fn_len);
3588
3589         if (check_col(pinfo->cinfo, COL_INFO)) {
3590                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3591                     format_text(fn, strlen(fn)));
3592         }
3593
3594         END_OF_SMB
3595
3596         return offset;
3597 }
3598
3599 static int
3600 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3601 {
3602         guint8 wc;
3603         guint16 bc, fid;
3604
3605         WORD_COUNT;
3606
3607         /* fid */
3608         fid = tvb_get_letohs(tvb, offset);
3609         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3610         offset += 2;
3611
3612         /* last write time */
3613         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3614
3615         BYTE_COUNT;
3616
3617         END_OF_SMB
3618
3619         return offset;
3620 }
3621
3622 static int
3623 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3624 {
3625         smb_info_t *si = pinfo->private_data;
3626         int fn_len;
3627         const char *fn;
3628         guint8 wc;
3629         guint16 bc;
3630
3631         DISSECTOR_ASSERT(si);
3632
3633         WORD_COUNT;
3634
3635         /* search attributes */
3636         offset = dissect_search_attributes(tvb, tree, offset);
3637
3638         BYTE_COUNT;
3639
3640         /* buffer format */
3641         CHECK_BYTE_COUNT(1);
3642         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3643         COUNT_BYTES(1);
3644
3645         /* file name */
3646         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3647                 FALSE, FALSE, &bc);
3648         if (fn == NULL)
3649                 goto endofcommand;
3650         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3651                 fn);
3652         COUNT_BYTES(fn_len);
3653
3654         if (check_col(pinfo->cinfo, COL_INFO)) {
3655                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3656                     format_text(fn, strlen(fn)));
3657         }
3658
3659         END_OF_SMB
3660
3661         return offset;
3662 }
3663
3664 static int
3665 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3666 {
3667         smb_info_t *si = pinfo->private_data;
3668         int fn_len;
3669         const char *fn;
3670         guint8 wc;
3671         guint16 bc;
3672
3673         DISSECTOR_ASSERT(si);
3674
3675         WORD_COUNT;
3676
3677         /* search attributes */
3678         offset = dissect_search_attributes(tvb, tree, offset);
3679
3680         BYTE_COUNT;
3681
3682         /* buffer format */
3683         CHECK_BYTE_COUNT(1);
3684         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3685         COUNT_BYTES(1);
3686
3687         /* old file name */
3688         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3689                 FALSE, FALSE, &bc);
3690         if (fn == NULL)
3691                 goto endofcommand;
3692         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3693                 fn);
3694         COUNT_BYTES(fn_len);
3695
3696         if (check_col(pinfo->cinfo, COL_INFO)) {
3697                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3698                     format_text(fn, strlen(fn)));
3699         }
3700
3701         /* buffer format */
3702         CHECK_BYTE_COUNT(1);
3703         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3704         COUNT_BYTES(1);
3705
3706         /* file name */
3707         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3708                 FALSE, FALSE, &bc);
3709         if (fn == NULL)
3710                 goto endofcommand;
3711         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3712                 fn);
3713         COUNT_BYTES(fn_len);
3714
3715         if (check_col(pinfo->cinfo, COL_INFO)) {
3716                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3717                     format_text(fn, strlen(fn)));
3718         }
3719
3720         END_OF_SMB
3721
3722         return offset;
3723 }
3724
3725 static int
3726 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3727 {
3728         smb_info_t *si = pinfo->private_data;
3729         int fn_len;
3730         const char *fn;
3731         guint8 wc;
3732         guint16 bc;
3733
3734         DISSECTOR_ASSERT(si);
3735
3736         WORD_COUNT;
3737
3738         /* search attributes */
3739         offset = dissect_search_attributes(tvb, tree, offset);
3740
3741         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3742         offset += 2;
3743
3744         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3745         offset += 4;
3746
3747         BYTE_COUNT;
3748
3749         /* buffer format */
3750         CHECK_BYTE_COUNT(1);
3751         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3752         COUNT_BYTES(1);
3753
3754         /* old file name */
3755         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3756                 FALSE, FALSE, &bc);
3757         if (fn == NULL)
3758                 goto endofcommand;
3759         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3760                 fn);
3761         COUNT_BYTES(fn_len);
3762
3763         if (check_col(pinfo->cinfo, COL_INFO)) {
3764                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3765                     format_text(fn, strlen(fn)));
3766         }
3767
3768         /* buffer format */
3769         CHECK_BYTE_COUNT(1);
3770         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3771         COUNT_BYTES(1);
3772
3773         /* file name */
3774         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3775                 FALSE, FALSE, &bc);
3776         if (fn == NULL)
3777                 goto endofcommand;
3778         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3779                 fn);
3780         COUNT_BYTES(fn_len);
3781
3782         if (check_col(pinfo->cinfo, COL_INFO)) {
3783                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3784                     format_text(fn, strlen(fn)));
3785         }
3786
3787         END_OF_SMB
3788
3789         return offset;
3790 }
3791
3792
3793 static int
3794 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3795 {
3796         smb_info_t *si = pinfo->private_data;
3797         guint16 bc;
3798         guint8 wc;
3799         const char *fn;
3800         int fn_len;
3801
3802         DISSECTOR_ASSERT(si);
3803
3804         WORD_COUNT;
3805
3806         BYTE_COUNT;
3807
3808         /* Buffer Format */
3809         CHECK_BYTE_COUNT(1);
3810         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3811         COUNT_BYTES(1);
3812
3813         /* File Name */
3814         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3815                 FALSE, FALSE, &bc);
3816         if (fn == NULL)
3817                 goto endofcommand;
3818         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3819                 fn);
3820         COUNT_BYTES(fn_len);
3821
3822         if (check_col(pinfo->cinfo, COL_INFO)) {
3823                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3824                     format_text(fn, strlen(fn)));
3825         }
3826
3827         END_OF_SMB
3828
3829         return offset;
3830 }
3831
3832 static int
3833 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3834 {
3835         guint16 bc;
3836         guint8 wc;
3837
3838         WORD_COUNT;
3839
3840         /* File Attributes */
3841         offset = dissect_file_attributes(tvb, tree, offset, 2);
3842
3843         /* Last Write Time */
3844         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3845
3846         /* File Size */
3847         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3848         offset += 4;
3849
3850         /* 10 reserved bytes */
3851         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3852         offset += 10;
3853
3854         BYTE_COUNT;
3855
3856         END_OF_SMB
3857
3858         return offset;
3859 }
3860
3861 static int
3862 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3863 {
3864         smb_info_t *si = pinfo->private_data;
3865         int fn_len;
3866         const char *fn;
3867         guint8 wc;
3868         guint16 bc;
3869
3870         DISSECTOR_ASSERT(si);
3871
3872         WORD_COUNT;
3873
3874         /* file attributes */
3875         offset = dissect_file_attributes(tvb, tree, offset, 2);
3876
3877         /* last write time */
3878         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3879
3880         /* 10 reserved bytes */
3881         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3882         offset += 10;
3883
3884         BYTE_COUNT;
3885
3886         /* buffer format */
3887         CHECK_BYTE_COUNT(1);
3888         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3889         COUNT_BYTES(1);
3890
3891         /* file name */
3892         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3893                 FALSE, FALSE, &bc);
3894         if (fn == NULL)
3895                 goto endofcommand;
3896         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3897                 fn);
3898         COUNT_BYTES(fn_len);
3899
3900         if (check_col(pinfo->cinfo, COL_INFO)) {
3901                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3902                     format_text(fn, strlen(fn)));
3903         }
3904
3905         END_OF_SMB
3906
3907         return offset;
3908 }
3909
3910 static int
3911 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3912 {
3913         guint8 wc;
3914         guint16 cnt=0, bc;
3915         guint32 ofs=0;
3916         smb_info_t *si;
3917         unsigned int fid;
3918
3919         WORD_COUNT;
3920
3921         /* fid */
3922         fid = tvb_get_letohs(tvb, offset);
3923         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
3924         offset += 2;
3925         if (!pinfo->fd->flags.visited) {
3926                 /* remember the FID for the processing of the response */
3927                 si = (smb_info_t *)pinfo->private_data;
3928                 DISSECTOR_ASSERT(si);
3929                 if (si->sip) {
3930                         si->sip->extra_info=GUINT_TO_POINTER(fid);
3931                         si->sip->extra_info_type=SMB_EI_FID;
3932                 }
3933         }
3934
3935         /* read count */
3936         cnt = tvb_get_letohs(tvb, offset);
3937         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3938         offset += 2;
3939
3940         /* offset */
3941         ofs = tvb_get_letohl(tvb, offset);
3942         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3943         offset += 4;
3944
3945         if (check_col(pinfo->cinfo, COL_INFO))
3946                 col_append_fstr(pinfo->cinfo, COL_INFO,
3947                                 ", %u byte%s at offset %u", cnt,
3948                                 (cnt == 1) ? "" : "s", ofs);
3949
3950         /* remaining */
3951         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3952         offset += 2;
3953
3954         BYTE_COUNT;
3955
3956         END_OF_SMB
3957
3958         return offset;
3959 }
3960
3961 int
3962 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3963 {
3964         int tvblen;
3965
3966         if(bc>datalen){
3967                 /* We have some initial padding bytes. */
3968                 /* XXX - use the data offset here instead? */
3969                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3970                         TRUE);
3971                 offset += bc-datalen;
3972                 bc = datalen;
3973         }
3974         tvblen = tvb_length_remaining(tvb, offset);
3975         if(bc>tvblen){
3976                 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);
3977                 offset += tvblen;
3978         } else {
3979                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3980                 offset += bc;
3981         }
3982         return offset;
3983 }
3984
3985 static int
3986 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3987     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3988 {
3989         int tvblen;
3990         tvbuff_t *dcerpc_tvb;
3991
3992         if(bc>datalen){
3993                 /* We have some initial padding bytes. */
3994                 /* XXX - use the data offset here instead? */
3995                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3996                         TRUE);
3997                 offset += bc-datalen;
3998                 bc = datalen;
3999         }
4000         tvblen = tvb_length_remaining(tvb, offset);
4001         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4002         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4003         if(bc>tvblen)
4004                 offset += tvblen;
4005         else
4006                 offset += bc;
4007         return offset;
4008 }
4009
4010 /*
4011  * transporting DCERPC over SMB seems to be implemented in various
4012  * ways. We might just assume it can be done by an almost random
4013  * mix of Trans/Read/Write calls
4014  *
4015  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4016  * and let him sort them out
4017  */
4018 static int
4019 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4020     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4021     guint16 datalen, guint32 ofs, guint16 fid)
4022 {
4023         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4024
4025         DISSECTOR_ASSERT(si);
4026
4027         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
4028                 /* dcerpc call */
4029                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4030                     top_tree, offset, bc, datalen, fid);
4031         } else {
4032                 /* ordinary file data */
4033                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4034         }
4035 }
4036
4037 static int
4038 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4039 {
4040         guint16 cnt=0, bc;
4041         guint8 wc;
4042         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4043         int fid=0;
4044
4045         DISSECTOR_ASSERT(si);
4046
4047         WORD_COUNT;
4048
4049         /* read count */
4050         cnt = tvb_get_letohs(tvb, offset);
4051         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4052         offset += 2;
4053
4054         /* 8 reserved bytes */
4055         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4056         offset += 8;
4057
4058         /* If we have seen the request, then print which FID this refers to */
4059         /* first check if we have seen the request */
4060         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type == SMB_EI_FID){
4061                 fid=GPOINTER_TO_INT(si->sip->extra_info);
4062                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
4063         }
4064
4065         BYTE_COUNT;
4066
4067         /* buffer format */
4068         CHECK_BYTE_COUNT(1);
4069         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4070         COUNT_BYTES(1);
4071
4072         /* data len */
4073         CHECK_BYTE_COUNT(2);
4074         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4075         COUNT_BYTES(2);
4076
4077         /* file data, might be DCERPC on a pipe */
4078         if(bc){
4079                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4080                     top_tree, offset, bc, bc, 0, (guint16) fid);
4081                 bc = 0;
4082         }
4083
4084         END_OF_SMB
4085
4086         return offset;
4087 }
4088
4089 static int
4090 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4091 {
4092         guint16 cnt, bc;
4093         guint8 wc;
4094
4095         WORD_COUNT;
4096
4097         /* read count */
4098         cnt = tvb_get_letohs(tvb, offset);
4099         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4100         offset += 2;
4101
4102         /* 8 reserved bytes */
4103         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4104         offset += 8;
4105
4106         BYTE_COUNT;
4107
4108         /* buffer format */
4109         CHECK_BYTE_COUNT(1);
4110         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4111         COUNT_BYTES(1);
4112
4113         /* data len */
4114         CHECK_BYTE_COUNT(2);
4115         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4116         COUNT_BYTES(2);
4117
4118         END_OF_SMB
4119
4120         return offset;
4121 }
4122
4123
4124 static int
4125 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4126 {
4127         guint32 ofs=0;
4128         guint16 cnt=0, bc, fid=0;
4129         guint8 wc;
4130
4131         WORD_COUNT;
4132
4133         /* fid */
4134         fid = tvb_get_letohs(tvb, offset);
4135         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4136         offset += 2;
4137
4138         /* write count */
4139         cnt = tvb_get_letohs(tvb, offset);
4140         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4141         offset += 2;
4142
4143         /* offset */
4144         ofs = tvb_get_letohl(tvb, offset);
4145         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4146         offset += 4;
4147
4148         if (check_col(pinfo->cinfo, COL_INFO))
4149                 col_append_fstr(pinfo->cinfo, COL_INFO,
4150                                 ", %u byte%s at offset %u", cnt,
4151                                 (cnt == 1) ? "" : "s", ofs);
4152
4153         /* remaining */
4154         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4155         offset += 2;
4156
4157         BYTE_COUNT;
4158
4159         /* buffer format */
4160         CHECK_BYTE_COUNT(1);
4161         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4162         COUNT_BYTES(1);
4163
4164         /* data len */
4165         CHECK_BYTE_COUNT(2);
4166         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4167         COUNT_BYTES(2);
4168
4169         /* file data, might be DCERPC on a pipe */
4170         if (bc != 0) {
4171                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4172                     top_tree, offset, bc, bc, ofs, fid);
4173                 bc = 0;
4174         }
4175
4176         END_OF_SMB
4177
4178         return offset;
4179 }
4180
4181 static int
4182 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4183 {
4184         guint8 wc;
4185         guint16 bc, cnt;
4186
4187         WORD_COUNT;
4188
4189         /* write count */
4190         cnt = tvb_get_letohs(tvb, offset);
4191         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4192         offset += 2;
4193
4194         if (check_col(pinfo->cinfo, COL_INFO))
4195                 col_append_fstr(pinfo->cinfo, COL_INFO,
4196                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4197
4198         BYTE_COUNT;
4199
4200         END_OF_SMB
4201
4202         return offset;
4203 }
4204
4205 static int
4206 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4207 {
4208         guint8 wc;
4209         guint16 bc, fid;
4210
4211         WORD_COUNT;
4212
4213         /* fid */
4214         fid = tvb_get_letohs(tvb, offset);
4215         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4216         offset += 2;
4217
4218         /* lock count */
4219         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
4220         offset += 4;
4221
4222         /* offset */
4223         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4224         offset += 4;
4225
4226         BYTE_COUNT;
4227
4228         END_OF_SMB
4229
4230         return offset;
4231 }
4232
4233 static int
4234 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4235 {
4236         smb_info_t *si = pinfo->private_data;
4237         int fn_len;
4238         const char *fn;
4239         guint8 wc;
4240         guint16 bc;
4241
4242         DISSECTOR_ASSERT(si);
4243
4244         WORD_COUNT;
4245
4246         /* 2 reserved bytes */
4247         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4248         offset += 2;
4249
4250         /* Creation time */
4251         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4252
4253         BYTE_COUNT;
4254
4255         /* buffer format */
4256         CHECK_BYTE_COUNT(1);
4257         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4258         COUNT_BYTES(1);
4259
4260         /* directory name */
4261         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4262                 FALSE, FALSE, &bc);
4263         if (fn == NULL)
4264                 goto endofcommand;
4265         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4266                 fn);
4267         COUNT_BYTES(fn_len);
4268
4269         if (check_col(pinfo->cinfo, COL_INFO)) {
4270                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4271                     format_text(fn, strlen(fn)));
4272         }
4273
4274         END_OF_SMB
4275
4276         return offset;
4277 }
4278
4279 static int
4280 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4281 {
4282         smb_info_t *si = pinfo->private_data;
4283         int fn_len;
4284         const char *fn;
4285         guint8 wc;
4286         guint16 bc, fid;
4287
4288         DISSECTOR_ASSERT(si);
4289
4290         WORD_COUNT;
4291
4292         /* fid */
4293         fid = tvb_get_letohs(tvb, offset);
4294         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
4295         offset += 2;
4296
4297         BYTE_COUNT;
4298
4299         /* buffer format */
4300         CHECK_BYTE_COUNT(1);
4301         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4302         COUNT_BYTES(1);
4303
4304         /* file name */
4305         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4306                 FALSE, FALSE, &bc);
4307         if (fn == NULL)
4308                 goto endofcommand;
4309         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4310                 fn);
4311         COUNT_BYTES(fn_len);
4312
4313         END_OF_SMB
4314
4315         return offset;
4316 }
4317
4318 static const value_string seek_mode_vals[] = {
4319         {0,     "From Start Of File"},
4320         {1,     "From Current Position"},
4321         {2,     "From End Of File"},
4322         {0,     NULL}
4323 };
4324
4325 static int
4326 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4327 {
4328         guint8 wc;
4329         guint16 bc, fid;
4330
4331         WORD_COUNT;
4332
4333         /* fid */
4334         fid = tvb_get_letohs(tvb, offset);
4335         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4336         offset += 2;
4337
4338         /* Seek Mode */
4339         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
4340         offset += 2;
4341
4342         /* offset */
4343         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4344         offset += 4;
4345
4346         BYTE_COUNT;
4347
4348         END_OF_SMB
4349
4350         return offset;
4351 }
4352
4353 static int
4354 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4355 {
4356         guint8 wc;
4357         guint16 bc;
4358
4359         WORD_COUNT;
4360
4361         /* offset */
4362         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4363         offset += 4;
4364
4365         BYTE_COUNT;
4366
4367         END_OF_SMB
4368
4369         return offset;
4370 }
4371
4372 static int
4373 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4374 {
4375         guint8 wc;
4376         guint16 bc, fid;
4377
4378         WORD_COUNT;
4379
4380         /* fid */
4381         fid = tvb_get_letohs(tvb, offset);
4382         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4383         offset += 2;
4384
4385         /* create time */
4386         offset = dissect_smb_datetime(tvb, tree, offset,
4387                 hf_smb_create_time,
4388                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4389
4390         /* access time */
4391         offset = dissect_smb_datetime(tvb, tree, offset,
4392                 hf_smb_access_time,
4393                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4394
4395         /* last write time */
4396         offset = dissect_smb_datetime(tvb, tree, offset,
4397                 hf_smb_last_write_time,
4398                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4399
4400         BYTE_COUNT;
4401
4402         END_OF_SMB
4403
4404         return offset;
4405 }
4406
4407 static int
4408 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4409 {
4410         guint8 wc;
4411         guint16 bc;
4412
4413         WORD_COUNT;
4414
4415         /* create time */
4416         offset = dissect_smb_datetime(tvb, tree, offset,
4417                 hf_smb_create_time,
4418                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4419
4420         /* access time */
4421         offset = dissect_smb_datetime(tvb, tree, offset,
4422                 hf_smb_access_time,
4423                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4424
4425         /* last write time */
4426         offset = dissect_smb_datetime(tvb, tree, offset,
4427                 hf_smb_last_write_time,
4428                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4429
4430         /* data size */
4431         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
4432         offset += 4;
4433
4434         /* allocation size */
4435         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4436         offset += 4;
4437
4438         /* File Attributes */
4439         offset = dissect_file_attributes(tvb, tree, offset, 2);
4440
4441         BYTE_COUNT;
4442
4443         END_OF_SMB
4444
4445         return offset;
4446 }
4447
4448 static int
4449 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4450 {
4451         guint8 wc;
4452         guint16 cnt=0;
4453         guint16 bc, fid;
4454
4455         WORD_COUNT;
4456
4457         /* fid */
4458         fid = tvb_get_letohs(tvb, offset);
4459         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
4460         offset += 2;
4461
4462         /* write count */
4463         cnt = tvb_get_letohs(tvb, offset);
4464         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4465         offset += 2;
4466
4467         /* offset */
4468         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4469         offset += 4;
4470
4471         /* last write time */
4472         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4473
4474         if(wc==12){
4475                 /* 12 reserved bytes */
4476                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
4477                 offset += 12;
4478         }
4479
4480         BYTE_COUNT;
4481
4482         /* 1 pad byte */
4483         CHECK_BYTE_COUNT(1);
4484         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
4485         COUNT_BYTES(1);
4486
4487         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4488         bc = 0; /* XXX */
4489
4490         END_OF_SMB
4491
4492         return offset;
4493 }
4494
4495 static int
4496 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4497 {
4498         guint8 wc;
4499         guint16 bc;
4500
4501         WORD_COUNT;
4502
4503         /* write count */
4504         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4505         offset += 2;
4506
4507         BYTE_COUNT;
4508
4509         END_OF_SMB
4510
4511         return offset;
4512 }
4513
4514 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4515    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4516 */
4517 static gchar *
4518 smbext20_timeout_msecs_to_str(gint32 time)
4519 {
4520         gchar *buf;
4521 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4522
4523         if (time <= 0) {
4524                 buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4525                 if (time == 0) {
4526                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4527                 } else if (time == -1) {
4528                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4529                 } else if (time == -2) {
4530                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4531                 } else {
4532                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
4533                 }
4534                 return buf;
4535         }
4536
4537         return time_msecs_to_str(time);
4538 }
4539
4540 static int
4541 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4542 {
4543         guint8 wc;
4544         guint16 bc, fid;
4545         guint32 to;
4546
4547         WORD_COUNT;
4548
4549         /* fid */
4550         fid = tvb_get_letohs(tvb, offset);
4551         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4552         offset += 2;
4553
4554         /* offset */
4555         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4556         offset += 4;
4557
4558         /* max count */
4559         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4560         offset += 2;
4561
4562         /* min count */
4563         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4564         offset += 2;
4565
4566         /* timeout */
4567         to = tvb_get_letohl(tvb, offset);
4568         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4569         offset += 4;
4570
4571         /* 2 reserved bytes */
4572         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4573         offset += 2;
4574
4575         if(wc==10){
4576                 /* high offset */
4577                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4578                 offset += 4;
4579         }
4580
4581         BYTE_COUNT;
4582
4583         END_OF_SMB
4584
4585         return offset;
4586 }
4587
4588 static int
4589 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4590 {
4591         guint8 wc;
4592         guint16 bc;
4593
4594         WORD_COUNT;
4595
4596         /* units */
4597         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
4598         offset += 2;
4599
4600         /* bpu */
4601         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
4602         offset += 2;
4603
4604         /* block size */
4605         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4606         offset += 2;
4607
4608         /* free units */
4609         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4610         offset += 2;
4611
4612         /* 2 reserved bytes */
4613         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4614         offset += 2;
4615
4616         BYTE_COUNT;
4617
4618         END_OF_SMB
4619
4620         return offset;
4621 }
4622
4623 static int
4624 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4625 {
4626         guint8 wc;
4627         guint16 bc, fid;
4628
4629         WORD_COUNT;
4630
4631         /* fid */
4632         fid = tvb_get_letohs(tvb, offset);
4633         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4634         offset += 2;
4635
4636         /* offset */
4637         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4638         offset += 4;
4639
4640         /* max count */
4641         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4642         offset += 2;
4643
4644         /* min count */
4645         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4646         offset += 2;
4647
4648         /* 6 reserved bytes */
4649         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4650         offset += 6;
4651
4652         BYTE_COUNT;
4653
4654         END_OF_SMB
4655
4656         return offset;
4657 }
4658
4659 static int
4660 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4661 {
4662         guint16 datalen=0, bc;
4663         guint8 wc;
4664
4665         WORD_COUNT;
4666
4667         /* offset */
4668         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4669         offset += 4;
4670
4671         /* count */
4672         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4673         offset += 2;
4674
4675         /* 2 reserved bytes */
4676         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4677         offset += 2;
4678
4679         /* data compaction mode */
4680         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4681         offset += 2;
4682
4683         /* 2 reserved bytes */
4684         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4685         offset += 2;
4686
4687         /* data len */
4688         datalen = tvb_get_letohs(tvb, offset);
4689         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4690         offset += 2;
4691
4692         /* data offset */
4693         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4694         offset += 2;
4695
4696         BYTE_COUNT;
4697
4698         /* file data */
4699         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4700         bc = 0;
4701
4702         END_OF_SMB
4703
4704         return offset;
4705 }
4706
4707
4708 static const true_false_string tfs_write_mode_write_through = {
4709         "WRITE THROUGH requested",
4710         "Write through not requested"
4711 };
4712 static const true_false_string tfs_write_mode_return_remaining = {
4713         "RETURN REMAINING (pipe/dev) requested",
4714         "DON'T return remaining (pipe/dev)"
4715 };
4716 static const true_false_string tfs_write_mode_raw = {
4717         "Use WriteRawNamedPipe (pipe)",
4718         "DON'T use WriteRawNamedPipe (pipe)"
4719 };
4720 static const true_false_string tfs_write_mode_message_start = {
4721         "This is the START of a MESSAGE (pipe)",
4722         "This is NOT the start of a message (pipe)"
4723 };
4724 static const true_false_string tfs_write_mode_connectionless = {
4725         "CONNECTIONLESS mode requested",
4726         "Connectionless mode NOT requested"
4727 };
4728
4729 #define WRITE_MODE_CONNECTIONLESS       0x0080
4730 #define WRITE_MODE_MESSAGE_START        0x0008
4731 #define WRITE_MODE_RAW                  0x0004
4732 #define WRITE_MODE_RETURN_REMAINING     0x0002
4733 #define WRITE_MODE_WRITE_THROUGH        0x0001
4734
4735 static int
4736 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4737 {
4738         guint16 mask;
4739         proto_item *item = NULL;
4740         proto_tree *tree = NULL;
4741
4742         mask = tvb_get_letohs(tvb, offset);
4743
4744         if(parent_tree){
4745                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4746                         "Write Mode: 0x%04x", mask);
4747                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4748         }
4749
4750         if(bm&WRITE_MODE_CONNECTIONLESS){
4751                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4752                         tvb, offset, 2, mask);
4753         }
4754         if(bm&WRITE_MODE_MESSAGE_START){
4755                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4756                         tvb, offset, 2, mask);
4757         }
4758         if(bm&WRITE_MODE_RAW){
4759                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4760                         tvb, offset, 2, mask);
4761         }
4762         if(bm&WRITE_MODE_RETURN_REMAINING){
4763                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4764                         tvb, offset, 2, mask);
4765         }
4766         if(bm&WRITE_MODE_WRITE_THROUGH){
4767                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4768                         tvb, offset, 2, mask);
4769         }
4770
4771         offset += 2;
4772         return offset;
4773 }
4774
4775 static int
4776 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4777 {
4778         guint32 to;
4779         guint16 datalen=0, bc, fid;
4780         guint8 wc;
4781
4782         WORD_COUNT;
4783
4784         /* fid */
4785         fid = tvb_get_letohs(tvb, offset);
4786         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4787         offset += 2;
4788
4789         /* total data length */
4790         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4791         offset += 2;
4792
4793         /* 2 reserved bytes */
4794         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4795         offset += 2;
4796
4797         /* offset */
4798         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4799         offset += 4;
4800
4801         /* timeout */
4802         to = tvb_get_letohl(tvb, offset);
4803         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4804         offset += 4;
4805
4806         /* mode */
4807         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4808
4809         /* 4 reserved bytes */
4810         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4811         offset += 4;
4812
4813         /* data len */
4814         datalen = tvb_get_letohs(tvb, offset);
4815         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4816         offset += 2;
4817
4818         /* data offset */
4819         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4820         offset += 2;
4821
4822         BYTE_COUNT;
4823
4824         /* file data */
4825         /* XXX - use the data offset to determine where the data starts? */
4826         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4827         bc = 0;
4828
4829         END_OF_SMB
4830
4831         return offset;
4832 }
4833
4834 static int
4835 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4836 {
4837         guint8 wc;
4838         guint16 bc;
4839
4840         WORD_COUNT;
4841
4842         /* remaining */
4843         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4844         offset += 2;
4845
4846         BYTE_COUNT;
4847
4848         END_OF_SMB
4849
4850         return offset;
4851 }
4852
4853 static int
4854 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4855 {
4856         guint32 to;
4857         guint16 datalen=0, bc, fid;
4858         guint8 wc;
4859
4860         WORD_COUNT;
4861
4862         /* fid */
4863         fid = tvb_get_letohs(tvb, offset);
4864         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4865         offset += 2;
4866
4867         /* total data length */
4868         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4869         offset += 2;
4870
4871         /* 2 reserved bytes */
4872         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4873         offset += 2;
4874
4875         /* offset */
4876         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4877         offset += 4;
4878
4879         /* timeout */
4880         to = tvb_get_letohl(tvb, offset);
4881         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4882         offset += 4;
4883
4884         /* mode */
4885         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4886
4887         /* request mask */
4888         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4889         offset += 4;
4890
4891         /* data len */
4892         datalen = tvb_get_letohs(tvb, offset);
4893         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4894         offset += 2;
4895
4896         /* data offset */
4897         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4898         offset += 2;
4899
4900         BYTE_COUNT;
4901
4902         /* file data */
4903         /* XXX - use the data offset to determine where the data starts? */
4904         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4905         bc = 0;
4906
4907         END_OF_SMB
4908
4909         return offset;
4910 }
4911
4912 static int
4913 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4914 {
4915         guint8 wc;
4916         guint16 bc;
4917
4918         WORD_COUNT;
4919
4920         /* response mask */
4921         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4922         offset += 4;
4923
4924         BYTE_COUNT;
4925
4926         END_OF_SMB
4927
4928         return offset;
4929 }
4930
4931 static int
4932 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4933 {
4934         guint8 wc;
4935         guint16 bc;
4936
4937         WORD_COUNT;
4938
4939         /* sid */
4940         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4941         offset += 2;
4942
4943         BYTE_COUNT;
4944
4945         END_OF_SMB
4946
4947         return offset;
4948 }
4949
4950 static int
4951 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4952     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4953     gboolean has_find_id)
4954 {
4955         proto_item *item = NULL;
4956         proto_tree *tree = NULL;
4957         smb_info_t *si = pinfo->private_data;
4958         int fn_len;
4959         const char *fn;
4960         char fname[11+1];
4961
4962         DISSECTOR_ASSERT(si);
4963
4964         if(parent_tree){
4965                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4966                         "Resume Key");
4967                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4968         }
4969
4970         /* reserved byte */
4971         CHECK_BYTE_COUNT_SUBR(1);
4972         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4973         COUNT_BYTES_SUBR(1);
4974
4975         /* file name */
4976         fn_len = 11;
4977         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
4978                 TRUE, TRUE, bcp);
4979         CHECK_STRING_SUBR(fn);
4980         /* ensure that it's null-terminated */
4981         strncpy(fname, fn, 11);
4982         fname[11] = '\0';
4983         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4984                 fname);
4985         COUNT_BYTES_SUBR(fn_len);
4986
4987         if (has_find_id) {
4988                 CHECK_BYTE_COUNT_SUBR(1);
4989                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4990                 COUNT_BYTES_SUBR(1);
4991
4992                 /* server cookie */
4993                 CHECK_BYTE_COUNT_SUBR(4);
4994                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4995                 COUNT_BYTES_SUBR(4);
4996         } else {
4997                 /* server cookie */
4998                 CHECK_BYTE_COUNT_SUBR(5);
4999                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
5000                 COUNT_BYTES_SUBR(5);
5001         }
5002
5003         /* client cookie */
5004         CHECK_BYTE_COUNT_SUBR(4);
5005         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
5006         COUNT_BYTES_SUBR(4);
5007
5008         *trunc = FALSE;
5009         return offset;
5010 }
5011
5012 static int
5013 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5014     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5015     gboolean has_find_id)
5016 {
5017         proto_item *item = NULL;
5018         proto_tree *tree = NULL;
5019         smb_info_t *si = pinfo->private_data;
5020         int fn_len;
5021         const char *fn;
5022         char fname[13+1];
5023
5024         DISSECTOR_ASSERT(si);
5025
5026         if(parent_tree){
5027                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5028                         "Directory Information");
5029                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5030         }
5031
5032         /* resume key */
5033         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5034             trunc, has_find_id);
5035         if (*trunc)
5036                 return offset;
5037
5038         /* File Attributes */
5039         CHECK_BYTE_COUNT_SUBR(1);
5040         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5041         *bcp -= 1;
5042
5043         /* last write time */
5044         CHECK_BYTE_COUNT_SUBR(4);
5045         offset = dissect_smb_datetime(tvb, tree, offset,
5046                 hf_smb_last_write_time,
5047                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5048                 TRUE);
5049         *bcp -= 4;
5050
5051         /* File Size */
5052         CHECK_BYTE_COUNT_SUBR(4);
5053         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5054         COUNT_BYTES_SUBR(4);
5055
5056         /* file name */
5057         fn_len = 13;
5058         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5059                 TRUE, TRUE, bcp);
5060         CHECK_STRING_SUBR(fn);
5061         /* ensure that it's null-terminated */
5062         strncpy(fname, fn, 13);
5063         fname[13] = '\0';
5064         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5065                 fname);
5066         COUNT_BYTES_SUBR(fn_len);
5067
5068         *trunc = FALSE;
5069         return offset;
5070 }
5071
5072
5073 static int
5074 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5075     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5076     gboolean has_find_id)
5077 {
5078         smb_info_t *si = pinfo->private_data;
5079         int fn_len;
5080         const char *fn;
5081         guint16 rkl;
5082         guint8 wc;
5083         guint16 bc;
5084         gboolean trunc;
5085
5086         DISSECTOR_ASSERT(si);
5087
5088         WORD_COUNT;
5089
5090         /* max count */
5091         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5092         offset += 2;
5093
5094         /* Search Attributes */
5095         offset = dissect_search_attributes(tvb, tree, offset);
5096
5097         BYTE_COUNT;
5098
5099         /* buffer format */
5100         CHECK_BYTE_COUNT(1);
5101         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5102         COUNT_BYTES(1);
5103
5104         /* file name */
5105         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5106                 TRUE, FALSE, &bc);
5107         if (fn == NULL)
5108                 goto endofcommand;
5109         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5110                 fn);
5111         COUNT_BYTES(fn_len);
5112
5113         if (check_col(pinfo->cinfo, COL_INFO)) {
5114                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5115                     format_text(fn, strlen(fn)));
5116         }
5117
5118         /* buffer format */
5119         CHECK_BYTE_COUNT(1);
5120         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5121         COUNT_BYTES(1);
5122
5123         /* resume key length */
5124         CHECK_BYTE_COUNT(2);
5125         rkl = tvb_get_letohs(tvb, offset);
5126         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5127         COUNT_BYTES(2);
5128
5129         /* resume key */
5130         if(rkl){
5131                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5132                     &bc, &trunc, has_find_id);
5133                 if (trunc)
5134                         goto endofcommand;
5135         }
5136
5137         END_OF_SMB
5138
5139         return offset;
5140 }
5141
5142 static int
5143 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5144     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5145 {
5146         return dissect_search_find_request(tvb, pinfo, tree, offset,
5147             smb_tree, FALSE);
5148 }
5149
5150 static int
5151 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5152     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5153 {
5154         return dissect_search_find_request(tvb, pinfo, tree, offset,
5155             smb_tree, TRUE);
5156 }
5157
5158 static int
5159 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5160     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5161 {
5162         return dissect_search_find_request(tvb, pinfo, tree, offset,
5163             smb_tree, TRUE);
5164 }
5165
5166 static int
5167 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5168     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5169     gboolean has_find_id)
5170 {
5171         guint16 count=0;
5172         guint8 wc;
5173         guint16 bc;
5174         gboolean trunc;
5175
5176         WORD_COUNT;
5177
5178         /* count */
5179         count = tvb_get_letohs(tvb, offset);
5180         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5181         offset += 2;
5182
5183         BYTE_COUNT;
5184
5185         /* buffer format */
5186         CHECK_BYTE_COUNT(1);
5187         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5188         COUNT_BYTES(1);
5189
5190         /* data len */
5191         CHECK_BYTE_COUNT(2);
5192         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
5193         COUNT_BYTES(2);
5194
5195         while(count--){
5196                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5197                     &bc, &trunc, has_find_id);
5198                 if (trunc)
5199                         goto endofcommand;
5200         }
5201
5202         END_OF_SMB
5203
5204         return offset;
5205 }
5206
5207 static int
5208 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5209 {
5210         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5211             FALSE);
5212 }
5213
5214 static int
5215 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5216 {
5217         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5218             TRUE);
5219 }
5220
5221 static int
5222 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5223     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5224 {
5225         guint8 wc;
5226         guint16 bc;
5227         guint16 data_len;
5228
5229         WORD_COUNT;
5230
5231         /* reserved */
5232         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5233         offset += 2;
5234
5235         BYTE_COUNT;
5236
5237         /* buffer format */
5238         CHECK_BYTE_COUNT(1);
5239         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5240         COUNT_BYTES(1);
5241
5242         /* data len */
5243         CHECK_BYTE_COUNT(2);
5244         data_len = tvb_get_ntohs(tvb, offset);
5245         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5246         COUNT_BYTES(2);
5247
5248         if (data_len != 0) {
5249                 CHECK_BYTE_COUNT(data_len);
5250                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5251                     data_len, TRUE);
5252                 COUNT_BYTES(data_len);
5253         }
5254
5255         END_OF_SMB
5256
5257         return offset;
5258 }
5259
5260 static const value_string locking_ol_vals[] = {
5261         {0,     "Client is not holding oplock on this file"},
5262         {1,     "Level 2 oplock currently held by client"},
5263         {0, NULL}
5264 };
5265
5266 static const true_false_string tfs_lock_type_large = {
5267         "Large file locking format requested",
5268         "Large file locking format not requested"
5269 };
5270 static const true_false_string tfs_lock_type_cancel = {
5271         "Cancel outstanding lock request",
5272         "Don't cancel outstanding lock request"
5273 };
5274 static const true_false_string tfs_lock_type_change = {
5275         "Change lock type",
5276         "Don't change lock type"
5277 };
5278 static const true_false_string tfs_lock_type_oplock = {
5279         "This is an oplock break notification/response",
5280         "This is not an oplock break notification/response"
5281 };
5282 static const true_false_string tfs_lock_type_shared = {
5283         "This is a shared lock",
5284         "This is an exclusive lock"
5285 };
5286 static int
5287 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5288 {
5289         guint8  wc, cmd=0xff, lt=0;
5290         guint16 andxoffset=0, un=0, ln=0, bc, fid;
5291         guint32 to;
5292         proto_item *litem = NULL;
5293         proto_tree *ltree = NULL;
5294         proto_item *it = NULL;
5295         proto_tree *tr = NULL;
5296         int old_offset = offset;
5297
5298         WORD_COUNT;
5299
5300         /* next smb command */
5301         cmd = tvb_get_guint8(tvb, offset);
5302         if(cmd!=0xff){
5303                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5304         } else {
5305                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5306         }
5307         offset += 1;
5308
5309         /* reserved byte */
5310         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5311         offset += 1;
5312
5313         /* andxoffset */
5314         andxoffset = tvb_get_letohs(tvb, offset);
5315         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5316         offset += 2;
5317
5318         /* fid */
5319         fid = tvb_get_letohs(tvb, offset);
5320         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5321         offset += 2;
5322
5323         /* lock type */
5324         lt = tvb_get_guint8(tvb, offset);
5325         if(tree){
5326                 litem = proto_tree_add_text(tree, tvb, offset, 1,
5327                         "Lock Type: 0x%02x", lt);
5328                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5329         }
5330         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5331                 tvb, offset, 1, lt);
5332         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5333                 tvb, offset, 1, lt);
5334         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5335                 tvb, offset, 1, lt);
5336         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5337                 tvb, offset, 1, lt);
5338         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5339                 tvb, offset, 1, lt);
5340         offset += 1;
5341
5342         /* oplock level */
5343         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
5344         offset += 1;
5345
5346         /* timeout */
5347         to = tvb_get_letohl(tvb, offset);
5348         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5349         offset += 4;
5350
5351         /* number of unlocks */
5352         un = tvb_get_letohs(tvb, offset);
5353         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5354         offset += 2;
5355
5356         /* number of locks */
5357         ln = tvb_get_letohs(tvb, offset);
5358         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5359         offset += 2;
5360
5361         BYTE_COUNT;
5362
5363         /* unlocks */
5364         if(un){
5365                 old_offset = offset;
5366
5367                 it = proto_tree_add_text(tree, tvb, offset, -1,
5368                         "Unlocks");
5369                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5370                 while(un--){
5371                         proto_item *litem = NULL;
5372                         proto_tree *ltree = NULL;
5373                         if(lt&0x10){
5374                                 guint64 val;
5375
5376                                 /* large lock format */
5377                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5378                                         "Unlock");
5379                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5380
5381                                 /* PID */
5382                                 CHECK_BYTE_COUNT(2);
5383                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5384                                 COUNT_BYTES(2);
5385
5386                                 /* 2 reserved bytes */
5387                                 CHECK_BYTE_COUNT(2);
5388                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5389                                 COUNT_BYTES(2);
5390
5391                                 /* offset */
5392                                 CHECK_BYTE_COUNT(8);
5393                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5394                                     | tvb_get_letohl(tvb, offset+4);
5395                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5396                                 COUNT_BYTES(8);
5397
5398                                 /* length */
5399                                 CHECK_BYTE_COUNT(8);
5400                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5401                                     | tvb_get_letohl(tvb, offset+4);
5402                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5403                                 COUNT_BYTES(8);
5404                         } else {
5405                                 /* normal lock format */
5406                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5407                                         "Unlock");
5408                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5409
5410                                 /* PID */
5411                                 CHECK_BYTE_COUNT(2);
5412                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5413                                 COUNT_BYTES(2);
5414
5415                                 /* offset */
5416                                 CHECK_BYTE_COUNT(4);
5417                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5418                                 COUNT_BYTES(4);
5419
5420                                 /* lock count */
5421                                 CHECK_BYTE_COUNT(4);
5422                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5423                                 COUNT_BYTES(4);
5424                         }
5425                 }
5426                 proto_item_set_len(it, offset-old_offset);
5427                 it = NULL;
5428         }
5429
5430         /* locks */
5431         if(ln){
5432                 old_offset = offset;
5433
5434                 it = proto_tree_add_text(tree, tvb, offset, -1,
5435                         "Locks");
5436                 tr = proto_item_add_subtree(it, ett_smb_locks);
5437                 while(ln--){
5438                         proto_item *litem = NULL;
5439                         proto_tree *ltree = NULL;
5440                         if(lt&0x10){
5441                                 guint64 val;
5442
5443                                 /* large lock format */
5444                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5445                                         "Lock");
5446                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5447
5448                                 /* PID */
5449                                 CHECK_BYTE_COUNT(2);
5450                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5451                                 COUNT_BYTES(2);
5452
5453                                 /* 2 reserved bytes */
5454                                 CHECK_BYTE_COUNT(2);
5455                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5456                                 COUNT_BYTES(2);
5457
5458                                 /* offset */
5459                                 CHECK_BYTE_COUNT(8);
5460                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5461                                     | tvb_get_letohl(tvb, offset+4);
5462                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5463                                 COUNT_BYTES(8);
5464
5465                                 /* length */
5466                                 CHECK_BYTE_COUNT(8);
5467                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5468                                     | tvb_get_letohl(tvb, offset+4);
5469                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5470                                 COUNT_BYTES(8);
5471                         } else {
5472                                 /* normal lock format */
5473                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5474                                         "Lock");
5475                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5476
5477                                 /* PID */
5478                                 CHECK_BYTE_COUNT(2);
5479                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5480                                 COUNT_BYTES(2);
5481
5482                                 /* offset */
5483                                 CHECK_BYTE_COUNT(4);
5484                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5485                                 COUNT_BYTES(4);
5486
5487                                 /* lock count */
5488                                 CHECK_BYTE_COUNT(4);
5489                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5490                                 COUNT_BYTES(4);
5491                         }
5492                 }
5493                 proto_item_set_len(it, offset-old_offset);
5494                 it = NULL;
5495         }
5496
5497         END_OF_SMB
5498
5499         if (it != NULL) {
5500                 /*
5501                  * We ran out of byte count in the middle of dissecting
5502                  * the locks or the unlocks; set the site of the item
5503                  * we were dissecting.
5504                  */
5505                 proto_item_set_len(it, offset-old_offset);
5506         }
5507
5508         if (cmd != 0xff) {      /* there is an andX command */
5509                 if (andxoffset < offset)
5510                         THROW(ReportedBoundsError);
5511                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5512         }
5513
5514         return offset;
5515 }
5516
5517 static int
5518 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5519 {
5520         guint8  wc, cmd=0xff;
5521         guint16 andxoffset=0;
5522         guint16 bc;
5523
5524         WORD_COUNT;
5525
5526         /* next smb command */
5527         cmd = tvb_get_guint8(tvb, offset);
5528         if(cmd!=0xff){
5529                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5530         } else {
5531                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5532         }
5533         offset += 1;
5534
5535         /* reserved byte */
5536         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5537         offset += 1;
5538
5539         /* andxoffset */
5540         andxoffset = tvb_get_letohs(tvb, offset);
5541         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5542         offset += 2;
5543
5544         BYTE_COUNT;
5545
5546         END_OF_SMB
5547
5548         if (cmd != 0xff) {      /* there is an andX command */
5549                 if (andxoffset < offset)
5550                         THROW(ReportedBoundsError);
5551                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5552         }
5553
5554         return offset;
5555 }
5556
5557
5558 const value_string oa_open_vals[] = {
5559         { 0,            "No action taken?"},
5560         { 1,            "The file existed and was opened"},
5561         { 2,            "The file did not exist but was created"},
5562         { 3,            "The file existed and was truncated"},
5563         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
5564         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
5565         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
5566         {0,     NULL}
5567 };
5568 static const true_false_string tfs_oa_lock = {
5569         "File is currently opened only by this user",
5570         "File is opened by another user (or mode not supported by server)"
5571 };
5572 static int
5573 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5574 {
5575         guint16 mask;
5576         proto_item *item = NULL;
5577         proto_tree *tree = NULL;
5578
5579         mask = tvb_get_letohs(tvb, offset);
5580
5581         if(parent_tree){
5582                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5583                         "Action: 0x%04x", mask);
5584                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5585         }
5586
5587         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5588                 tvb, offset, 2, mask);
5589         proto_tree_add_uint(tree, hf_smb_open_action_open,
5590                 tvb, offset, 2, mask);
5591
5592         offset += 2;
5593
5594         return offset;
5595 }
5596
5597 static const true_false_string tfs_open_flags_add_info = {
5598         "Additional information requested",
5599         "Additional information not requested"
5600 };
5601 static const true_false_string tfs_open_flags_ex_oplock = {
5602         "Exclusive oplock requested",
5603         "Exclusive oplock not requested"
5604 };
5605 static const true_false_string tfs_open_flags_batch_oplock = {
5606         "Batch oplock requested",
5607         "Batch oplock not requested"
5608 };
5609 static const true_false_string tfs_open_flags_ealen = {
5610         "Total length of EAs requested",
5611         "Total length of EAs not requested"
5612 };
5613 static int
5614 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5615 {
5616         guint16 mask;
5617         proto_item *item = NULL;
5618         proto_tree *tree = NULL;
5619
5620         mask = tvb_get_letohs(tvb, offset);
5621
5622         if(parent_tree){
5623                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5624                         "Flags: 0x%04x", mask);
5625                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5626         }
5627
5628         if(bm&0x0001){
5629                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5630                         tvb, offset, 2, mask);
5631         }
5632         if(bm&0x0002){
5633                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5634                         tvb, offset, 2, mask);
5635         }
5636         if(bm&0x0004){
5637                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5638                         tvb, offset, 2, mask);
5639         }
5640         if(bm&0x0008){
5641                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5642                         tvb, offset, 2, mask);
5643         }
5644
5645         offset += 2;
5646
5647         return offset;
5648 }
5649
5650 static const value_string filetype_vals[] = {
5651         { 0,            "Disk file or directory"},
5652         { 1,            "Named pipe in byte mode"},
5653         { 2,            "Named pipe in message mode"},
5654         { 3,            "Spooled printer"},
5655         {0, NULL}
5656 };
5657 static int
5658 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5659 {
5660         guint8  wc, cmd=0xff;
5661         guint16 andxoffset=0, bc;
5662         guint32 to;
5663         smb_info_t *si = pinfo->private_data;
5664         int fn_len;
5665         const char *fn;
5666
5667         DISSECTOR_ASSERT(si);
5668
5669         WORD_COUNT;
5670
5671         /* next smb command */
5672         cmd = tvb_get_guint8(tvb, offset);
5673         if(cmd!=0xff){
5674                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5675         } else {
5676                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5677         }
5678         offset += 1;
5679
5680         /* reserved byte */
5681         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5682         offset += 1;
5683
5684         /* andxoffset */
5685         andxoffset = tvb_get_letohs(tvb, offset);
5686         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5687         offset += 2;
5688
5689         /* open flags */
5690         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5691
5692         /* desired access */
5693         offset = dissect_access(tvb, tree, offset, "Desired");
5694
5695         /* Search Attributes */
5696         offset = dissect_search_attributes(tvb, tree, offset);
5697
5698         /* File Attributes */
5699         offset = dissect_file_attributes(tvb, tree, offset, 2);
5700
5701         /* creation time */
5702         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5703
5704         /* open function */
5705         offset = dissect_open_function(tvb, tree, offset);
5706
5707         /* allocation size */
5708         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5709         offset += 4;
5710
5711         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
5712         to = tvb_get_letohl(tvb, offset);
5713         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5714         offset += 4;
5715
5716         /* 4 reserved bytes */
5717         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5718         offset += 4;
5719
5720         BYTE_COUNT;
5721
5722         /* file name */
5723         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5724                 FALSE, FALSE, &bc);
5725         if (fn == NULL)
5726                 goto endofcommand;
5727         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5728                 fn);
5729         COUNT_BYTES(fn_len);
5730
5731         if (check_col(pinfo->cinfo, COL_INFO)) {
5732                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
5733                     format_text(fn, strlen(fn)));
5734         }
5735
5736         END_OF_SMB
5737
5738         if (cmd != 0xff) {      /* there is an andX command */
5739                 if (andxoffset < offset)
5740                         THROW(ReportedBoundsError);
5741                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5742         }
5743
5744         return offset;
5745 }
5746
5747 static const true_false_string tfs_ipc_state_nonblocking = {
5748         "Reads/writes return immediately if no data available",
5749         "Reads/writes block if no data available"
5750 };
5751 static const value_string ipc_state_endpoint_vals[] = {
5752         { 0,            "Consumer end of pipe"},
5753         { 1,            "Server end of pipe"},
5754         {0,     NULL}
5755 };
5756 static const value_string ipc_state_pipe_type_vals[] = {
5757         { 0,            "Byte stream pipe"},
5758         { 1,            "Message pipe"},
5759         {0,     NULL}
5760 };
5761 static const value_string ipc_state_read_mode_vals[] = {
5762         { 0,            "Read pipe as a byte stream"},
5763         { 1,            "Read messages from pipe"},
5764         {0,     NULL}
5765 };
5766
5767 int
5768 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5769     gboolean setstate)
5770 {
5771         guint16 mask;
5772         proto_item *item = NULL;
5773         proto_tree *tree = NULL;
5774
5775         mask = tvb_get_letohs(tvb, offset);
5776
5777         if(parent_tree){
5778                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5779                         "IPC State: 0x%04x", mask);
5780                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5781         }
5782
5783         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5784                 tvb, offset, 2, mask);
5785         if (!setstate) {
5786                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5787                         tvb, offset, 2, mask);
5788                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5789                         tvb, offset, 2, mask);
5790         }
5791         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5792                 tvb, offset, 2, mask);
5793         if (!setstate) {
5794                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5795                         tvb, offset, 2, mask);
5796         }
5797
5798         offset += 2;
5799
5800         return offset;
5801 }
5802
5803 static int
5804 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5805 {
5806         guint8  wc, cmd=0xff;
5807         guint16 andxoffset=0, bc;
5808         guint16 fid;
5809
5810         WORD_COUNT;
5811
5812         /* next smb command */
5813         cmd = tvb_get_guint8(tvb, offset);
5814         if(cmd!=0xff){
5815                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5816         } else {
5817                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5818         }
5819         offset += 1;
5820
5821         /* reserved byte */
5822         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5823         offset += 1;
5824
5825         /* andxoffset */
5826         andxoffset = tvb_get_letohs(tvb, offset);
5827         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5828         offset += 2;
5829
5830         /* fid */
5831         fid = tvb_get_letohs(tvb, offset);
5832         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
5833         offset += 2;
5834
5835         /* File Attributes */
5836         offset = dissect_file_attributes(tvb, tree, offset, 2);
5837
5838         /* last write time */
5839         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5840
5841         /* File Size */
5842         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5843         offset += 4;
5844
5845         /* granted access */
5846         offset = dissect_access(tvb, tree, offset, "Granted");
5847
5848         /* File Type */
5849         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5850         offset += 2;
5851
5852         /* IPC State */
5853         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5854
5855         /* open_action */
5856         offset = dissect_open_action(tvb, tree, offset);
5857
5858         /* server fid */
5859         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5860         offset += 4;
5861
5862         /* 2 reserved bytes */
5863         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5864         offset += 2;
5865
5866         BYTE_COUNT;
5867
5868         END_OF_SMB
5869
5870         if (cmd != 0xff) {      /* there is an andX command */
5871                 if (andxoffset < offset)
5872                         THROW(ReportedBoundsError);
5873                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5874         }
5875
5876         return offset;
5877 }
5878
5879 static int
5880 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5881 {
5882         guint8  wc, cmd=0xff;
5883         guint16 andxoffset=0, bc, maxcnt_low;
5884         guint32 maxcnt_high;
5885         guint32 maxcnt=0;
5886         guint32 ofs = 0;
5887         smb_info_t *si;
5888         unsigned int fid;
5889
5890         WORD_COUNT;
5891
5892         /* next smb command */
5893         cmd = tvb_get_guint8(tvb, offset);
5894         if(cmd!=0xff){
5895                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5896         } else {
5897                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5898         }
5899         offset += 1;
5900
5901         /* reserved byte */
5902         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5903         offset += 1;
5904
5905         /* andxoffset */
5906         andxoffset = tvb_get_letohs(tvb, offset);
5907         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5908         offset += 2;
5909
5910         /* fid */
5911         fid = tvb_get_letohs(tvb, offset);
5912         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
5913         offset += 2;
5914         if (!pinfo->fd->flags.visited) {
5915                 /* remember the FID for the processing of the response */
5916                 si = (smb_info_t *)pinfo->private_data;
5917                 DISSECTOR_ASSERT(si);
5918                 if (si->sip) {
5919                         si->sip->extra_info=GUINT_TO_POINTER(fid);
5920                         si->sip->extra_info_type=SMB_EI_FID;
5921                 }
5922         }
5923
5924         /* offset */
5925         ofs = tvb_get_letohl(tvb, offset);
5926         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5927         offset += 4;
5928
5929         /* max count low */
5930         maxcnt_low = tvb_get_letohs(tvb, offset);
5931         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5932         offset += 2;
5933
5934         /* min count */
5935         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5936         offset += 2;
5937
5938         /*
5939          * max count high
5940          *
5941          * XXX - we should really only do this in case we have seen
5942          * LARGE FILE being negotiated.  Unfortunately, we might not
5943          * have seen the negotiation phase in the capture....
5944          *
5945          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5946          * it's 32 bits, but the description says "High 16 bits of
5947          * MaxCount if CAP_LARGE_READX".
5948          *
5949          * The SMB File Sharing Protocol Extensions Version 2.0,
5950          * Document Version 3.3 spec doesn't speak of an extra 16
5951          * bits in max count, but it does show a 32-bit timeout
5952          * after the min count field.
5953          *
5954          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5955          * high count and a 16-bit reserved field.
5956          *
5957          * We fetch and display it as 32 bits.
5958          * 
5959          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5960          * bytes and we just ignore it.
5961          */
5962         maxcnt_high = tvb_get_letohl(tvb, offset);
5963         if(maxcnt_high==0xffffffff){
5964                 maxcnt_high=0;
5965         } else {
5966                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5967         }
5968
5969         offset += 4;
5970
5971         maxcnt=maxcnt_high;
5972         maxcnt=(maxcnt<<16)|maxcnt_low;
5973
5974         if (check_col(pinfo->cinfo, COL_INFO))
5975                 col_append_fstr(pinfo->cinfo, COL_INFO,
5976                                 ", %u byte%s at offset %u", maxcnt,
5977                                 (maxcnt == 1) ? "" : "s", ofs);
5978
5979         /* remaining */
5980         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5981         offset += 2;
5982
5983         if(wc==12){
5984                 /* high offset */
5985                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5986                 offset += 4;
5987         }
5988
5989         BYTE_COUNT;
5990
5991         END_OF_SMB
5992
5993         if (cmd != 0xff) {      /* there is an andX command */
5994                 if (andxoffset < offset)
5995                         THROW(ReportedBoundsError);
5996                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5997         }
5998
5999         return offset;
6000 }
6001
6002 static int
6003 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6004 {
6005         guint8  wc, cmd=0xff;
6006         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
6007         guint32 datalen=0, datalen_high;
6008         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6009         int fid=0;
6010
6011         DISSECTOR_ASSERT(si);
6012
6013         WORD_COUNT;
6014
6015         /* next smb command */
6016         cmd = tvb_get_guint8(tvb, offset);
6017         if(cmd!=0xff){
6018                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6019         } else {
6020                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6021         }
6022         offset += 1;
6023
6024         /* reserved byte */
6025         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6026         offset += 1;
6027
6028         /* andxoffset */
6029         andxoffset = tvb_get_letohs(tvb, offset);
6030         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6031         offset += 2;
6032
6033         /* If we have seen the request, then print which FID this refers to */
6034         /* first check if we have seen the request */
6035         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6036                 fid=GPOINTER_TO_INT(si->sip->extra_info);
6037                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
6038         }
6039
6040         /* remaining */
6041         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6042         offset += 2;
6043
6044         /* data compaction mode */
6045         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
6046         offset += 2;
6047
6048         /* 2 reserved bytes */
6049         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6050         offset += 2;
6051
6052         /* data len low */
6053         datalen_low = tvb_get_letohs(tvb, offset);
6054         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6055         offset += 2;
6056
6057         /* data offset */
6058         dataoffset=tvb_get_letohs(tvb, offset);
6059         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6060         offset += 2;
6061
6062         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6063         /* data length high */
6064         datalen_high = tvb_get_letohl(tvb, offset);
6065         if(datalen_high==0xffffffff){
6066                 datalen_high=0;
6067         } else {
6068                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6069         }
6070         offset += 4;
6071
6072         datalen=datalen_high;
6073         datalen=(datalen<<16)|datalen_low;
6074
6075
6076         if (check_col(pinfo->cinfo, COL_INFO))
6077                 col_append_fstr(pinfo->cinfo, COL_INFO,
6078                                 ", %u byte%s", datalen,
6079                                 (datalen == 1) ? "" : "s");
6080
6081
6082         /* 6 reserved bytes */
6083         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
6084         offset += 6;
6085
6086         BYTE_COUNT;
6087
6088         /* file data, might be DCERPC on a pipe */
6089         if(bc){
6090                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6091                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6092                 bc = 0;
6093         }
6094
6095         END_OF_SMB
6096
6097         if (cmd != 0xff) {      /* there is an andX command */
6098                 if (andxoffset < offset)
6099                         THROW(ReportedBoundsError);
6100                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6101         }
6102
6103         return offset;
6104 }
6105
6106 static int
6107 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6108 {
6109         guint32 ofs=0;
6110         guint8  wc, cmd=0xff;
6111         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
6112         guint32 datalen=0;
6113         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6114         unsigned int fid=0;
6115         guint16 mode = 0;
6116
6117         DISSECTOR_ASSERT(si);
6118
6119         WORD_COUNT;
6120
6121         /* next smb command */
6122         cmd = tvb_get_guint8(tvb, offset);
6123         if(cmd!=0xff){
6124                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6125         } else {
6126                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6127         }
6128         offset += 1;
6129
6130         /* reserved byte */
6131         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6132         offset += 1;
6133
6134         /* andxoffset */
6135         andxoffset = tvb_get_letohs(tvb, offset);
6136         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6137         offset += 2;
6138
6139         /* fid */
6140         fid = tvb_get_letohs(tvb, offset);
6141         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6142         offset += 2;
6143         if (!pinfo->fd->flags.visited) {
6144                 /* remember the FID for the processing of the response */
6145                 if (si->sip) {
6146                         si->sip->extra_info=GUINT_TO_POINTER(fid);
6147                         si->sip->extra_info_type=SMB_EI_FID;
6148                 }
6149         }
6150
6151         /* offset */
6152         ofs = tvb_get_letohl(tvb, offset);
6153         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6154         offset += 4;
6155
6156         /* reserved */
6157         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6158         offset += 4;
6159
6160         /* mode */
6161         mode = tvb_get_letohs(tvb, offset);
6162         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6163
6164         /* remaining */
6165         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6166         offset += 2;
6167
6168         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6169         /* data length high */
6170         datalen_high = tvb_get_letohs(tvb, offset);
6171         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6172         offset += 2;
6173
6174         /* data len low */
6175         datalen_low = tvb_get_letohs(tvb, offset);
6176         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6177         offset += 2;
6178
6179         datalen=datalen_high;
6180         datalen=(datalen<<16)|datalen_low;
6181
6182         /* data offset */
6183         dataoffset=tvb_get_letohs(tvb, offset);
6184         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6185         offset += 2;
6186
6187         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
6188         if (check_col(pinfo->cinfo, COL_INFO))
6189                 col_append_fstr(pinfo->cinfo, COL_INFO,
6190                                 ", %u byte%s at offset %u", datalen,
6191                                 (datalen == 1) ? "" : "s", ofs);
6192
6193         if(wc==14){
6194                 /* high offset */
6195                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6196                 offset += 4;
6197         }
6198
6199         BYTE_COUNT;
6200
6201         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6202            the first two bytes of the payload is the length of the data.
6203            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6204            be over the IPC$ share and thus they all transport DCERPC.
6205            (if we didnt already know that from the TreeConnect call)
6206         */
6207         if(mode&WRITE_MODE_MESSAGE_START){
6208                 if(mode&WRITE_MODE_RAW){
6209                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
6210                         offset += 2;
6211                         dataoffset += 2;
6212                         bc -= 2;
6213                         datalen -= 2;
6214                 }
6215                 if(!pinfo->fd->flags.visited){
6216                         /* In case we did not see the TreeConnect call,
6217                            store this TID here as well as a IPC TID 
6218                            so we know that future Read/Writes to this 
6219                            TID is (probably) DCERPC.
6220                         */
6221                         if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
6222                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6223                         }
6224                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6225                 }
6226                 if(si->sip){
6227                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
6228                 }
6229         }
6230
6231         /* file data, might be DCERPC on a pipe */
6232         if (bc != 0) {
6233                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6234                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6235                 bc = 0;
6236         }
6237
6238         END_OF_SMB
6239
6240         if (cmd != 0xff) {      /* there is an andX command */
6241                 if (andxoffset < offset)
6242                         THROW(ReportedBoundsError);
6243                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6244         }
6245
6246         return offset;
6247 }
6248
6249 static int
6250 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6251 {
6252         guint8  wc, cmd=0xff;
6253         guint16 andxoffset=0, bc, count_low, count_high;
6254         guint32 count=0;
6255         smb_info_t *si;
6256
6257         WORD_COUNT;
6258
6259         /* next smb command */
6260         cmd = tvb_get_guint8(tvb, offset);
6261         if(cmd!=0xff){
6262                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6263         } else {
6264                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6265         }
6266         offset += 1;
6267
6268         /* reserved byte */
6269         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6270         offset += 1;
6271
6272         /* andxoffset */
6273         andxoffset = tvb_get_letohs(tvb, offset);
6274         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6275         offset += 2;
6276
6277         /* If we have seen the request, then print which FID this refers to */
6278         si = (smb_info_t *)pinfo->private_data;
6279         DISSECTOR_ASSERT(si);
6280         /* first check if we have seen the request */
6281         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6282                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) GPOINTER_TO_UINT(si->sip->extra_info), FALSE, FALSE, FALSE);
6283         }
6284
6285         /* write count low */
6286         count_low = tvb_get_letohs(tvb, offset);
6287         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6288         offset += 2;
6289
6290         /* remaining */
6291         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6292         offset += 2;
6293
6294         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6295         /* write count high */
6296         count_high = tvb_get_letohs(tvb, offset);
6297         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6298         offset += 2;
6299
6300         count=count_high;
6301         count=(count<<16)|count_low;
6302
6303         if (check_col(pinfo->cinfo, COL_INFO))
6304                 col_append_fstr(pinfo->cinfo, COL_INFO,
6305                                 ", %u byte%s", count,
6306                                 (count == 1) ? "" : "s");
6307
6308         /* 2 reserved bytes */
6309         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6310         offset += 2;
6311
6312         BYTE_COUNT;
6313
6314         END_OF_SMB
6315
6316         if (cmd != 0xff) {      /* there is an andX command */
6317                 if (andxoffset < offset)
6318                         THROW(ReportedBoundsError);
6319                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6320         }
6321
6322         return offset;
6323 }
6324
6325
6326 static const true_false_string tfs_setup_action_guest = {
6327         "Logged in as GUEST",
6328         "Not logged in as GUEST"
6329 };
6330 static int
6331 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6332 {
6333         guint16 mask;
6334         proto_item *item = NULL;
6335         proto_tree *tree = NULL;
6336
6337         mask = tvb_get_letohs(tvb, offset);
6338
6339         if(parent_tree){
6340                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6341                         "Action: 0x%04x", mask);
6342                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
6343         }
6344
6345         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
6346                 tvb, offset, 2, mask);
6347
6348         offset += 2;
6349
6350         return offset;
6351 }
6352
6353
6354 static int
6355 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6356 {
6357         guint8  wc, cmd=0xff;
6358         guint16 bc;
6359         guint16 andxoffset=0;
6360         smb_info_t *si = pinfo->private_data;
6361         int an_len;
6362         const char *an;
6363         int dn_len;
6364         const char *dn;
6365         guint16 pwlen=0;
6366         guint16 sbloblen=0, sbloblen_short;
6367         guint16 apwlen=0, upwlen=0;
6368         gboolean unicodeflag;
6369         static int ntlmssp_tap_id = 0;
6370         const ntlmssp_header_t *ntlmssph;
6371
6372         if(!ntlmssp_tap_id){
6373                 GString *error_string;
6374                 /* We dont specify any callbacks at all.
6375                  * Instead we manually fetch the tapped data after the
6376                  * security blob has been fully dissected and before
6377                  * we exit from this dissector.
6378                  */
6379                 error_string=register_tap_listener("ntlmssp", NULL, NULL, NULL, NULL, NULL);
6380                 if(!error_string){
6381                         ntlmssp_tap_id=find_tap_id("ntlmssp");
6382                 }
6383         }
6384
6385         DISSECTOR_ASSERT(si);
6386
6387         WORD_COUNT;
6388
6389         /* next smb command */
6390         cmd = tvb_get_guint8(tvb, offset);
6391         if(cmd!=0xff){
6392                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6393         } else {
6394                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6395         }
6396         offset += 1;
6397
6398         /* reserved byte */
6399         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6400         offset += 1;
6401
6402         /* andxoffset */
6403         andxoffset = tvb_get_letohs(tvb, offset);
6404         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6405         offset += 2;
6406
6407         /* Maximum Buffer Size */
6408         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
6409         offset += 2;
6410
6411         /* Maximum Multiplex Count */
6412         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
6413         offset += 2;
6414
6415         /* VC Number */
6416         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
6417         offset += 2;
6418
6419         /* session key */
6420         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
6421         offset += 4;
6422
6423         switch (wc) {
6424         case 10:
6425                 /* password length, ASCII*/
6426                 pwlen = tvb_get_letohs(tvb, offset);
6427                 proto_tree_add_uint(tree, hf_smb_password_len,
6428                         tvb, offset, 2, pwlen);
6429                 offset += 2;
6430
6431                 /* 4 reserved bytes */
6432                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6433                 offset += 4;
6434
6435                 break;
6436
6437         case 12:
6438                 /* security blob length */
6439                 sbloblen = tvb_get_letohs(tvb, offset);
6440                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6441                 offset += 2;
6442
6443                 /* 4 reserved bytes */
6444                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6445                 offset += 4;
6446
6447                 /* capabilities */
6448                 dissect_negprot_capabilities(tvb, tree, offset);
6449                 offset += 4;
6450
6451                 break;
6452
6453         case 13:
6454                 /* password length, ANSI*/
6455                 apwlen = tvb_get_letohs(tvb, offset);
6456                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
6457                         tvb, offset, 2, apwlen);
6458                 offset += 2;
6459
6460                 /* password length, Unicode*/
6461                 upwlen = tvb_get_letohs(tvb, offset);
6462                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
6463                         tvb, offset, 2, upwlen);
6464                 offset += 2;
6465
6466                 /* 4 reserved bytes */
6467                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6468                 offset += 4;
6469
6470                 /* capabilities */
6471                 dissect_negprot_capabilities(tvb, tree, offset);
6472                 offset += 4;
6473
6474                 break;
6475         }
6476
6477         BYTE_COUNT;
6478
6479         if (wc==12) {
6480                 proto_item *blob_item;
6481
6482                 /* security blob */
6483                 /* If it runs past the end of the captured data, don't
6484                  * try to put all of it into the protocol tree as the
6485                  * raw security blob; we might get an exception on 
6486                  * short frames and then we will not see anything at all
6487                  * of the security blob.
6488                  */
6489                 sbloblen_short = sbloblen;
6490                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
6491                         sbloblen_short=tvb_length_remaining(tvb,offset);
6492                 }
6493                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6494                                                 tvb, offset, sbloblen_short,
6495                                                 TRUE);
6496
6497                 /* As an optimization, because Windows is perverse,
6498                    we check to see if NTLMSSP is the first part of the 
6499                    blob, and if so, call the NTLMSSP dissector,
6500                    otherwise we call the GSS-API dissector. This is because
6501                    Windows can request RAW NTLMSSP, but will happily handle
6502                    a client that wraps NTLMSSP in SPNEGO
6503                 */
6504
6505                 if(sbloblen){
6506                         tvbuff_t *blob_tvb;
6507                         proto_tree *blob_tree;
6508
6509                         blob_tree = proto_item_add_subtree(blob_item, 
6510                                                            ett_smb_secblob);
6511                         CHECK_BYTE_COUNT(sbloblen);
6512
6513                         /*
6514                          * Set the reported length of this to the reported
6515                          * length of the blob, rather than the amount of
6516                          * data available from the blob, so that we'll
6517                          * throw the right exception if it's too short.
6518                          */
6519                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
6520                                                   sbloblen);
6521
6522                         if (si && si->ct && si->ct->raw_ntlmssp &&
6523                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6524                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6525                                          blob_tree);
6526
6527                         }
6528                         else {
6529                           call_dissector(gssapi_handle, blob_tvb, 
6530                                          pinfo, blob_tree);
6531                         }
6532
6533                         /* If we have found a uid->acct_name mapping, store it */
6534                         if(!pinfo->fd->flags.visited && si->sip){
6535                                 int idx=0;
6536                                 if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
6537                                         if(ntlmssph && ntlmssph->type==3){
6538                                                 smb_uid_t *smb_uid;
6539         
6540                                                 smb_uid=se_alloc(sizeof(smb_uid_t));
6541                                                 smb_uid->logged_in=-1;
6542                                                 smb_uid->logged_out=-1;
6543                                                 smb_uid->domain=se_strdup(ntlmssph->domain_name);
6544                                                 smb_uid->account=se_strdup(ntlmssph->acct_name);
6545
6546                                                 si->sip->extra_info=smb_uid;
6547                                                 si->sip->extra_info_type=SMB_EI_UID;
6548                                         }
6549                                 }
6550                         }
6551
6552                         COUNT_BYTES(sbloblen);
6553                 }
6554
6555                 /* OS
6556                  * Eventhough this field should honour the unicode flag
6557                  * some ms clients gets this wrong.
6558                  * At least XP SP1 sends this in ASCII
6559                  * even when the unicode flag is on.
6560                  * Test if the first three bytes are "Win"
6561                  * and if so just override the flag.
6562                  */
6563                 unicodeflag=si->unicode;
6564                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6565                         unicodeflag=FALSE;
6566                 }
6567                 an = get_unicode_or_ascii_string(tvb, &offset,
6568                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6569                 if (an == NULL)
6570                         goto endofcommand;
6571                 proto_tree_add_string(tree, hf_smb_os, tvb,
6572                         offset, an_len, an);
6573                 COUNT_BYTES(an_len);
6574
6575                 /* LANMAN */
6576                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6577                  * padding/null string/whatever in front of this. W2K doesn't
6578                  * appear to. I suspect that's a bug that got fixed; I also
6579                  * suspect that, in practice, nobody ever looks at that field
6580                  * because the bug didn't appear to get fixed until NT 5.0....
6581                  *
6582                  * Eventhough this field should honour the unicode flag
6583                  * some ms clients gets this wrong.
6584                  * At least XP SP1 sends this in ASCII
6585                  * even when the unicode flag is on.
6586                  * Test if the first three bytes are "Win"
6587                  * and if so just override the flag.
6588                  */
6589                 unicodeflag=si->unicode;
6590                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6591                         unicodeflag=FALSE;
6592                 }
6593                 an = get_unicode_or_ascii_string(tvb, &offset,
6594                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6595                 if (an == NULL)
6596                         goto endofcommand;
6597                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6598                         offset, an_len, an);
6599                 COUNT_BYTES(an_len);
6600
6601                 /* Primary domain */
6602                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6603                  * byte in front of this, at least if all the strings are
6604                  * ASCII and the account name is empty. Another bug?
6605                  */
6606                 dn = get_unicode_or_ascii_string(tvb, &offset,
6607                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6608                 if (dn == NULL)
6609                         goto endofcommand;
6610                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6611                         offset, dn_len, dn);
6612                 COUNT_BYTES(dn_len);
6613         } else {
6614                 switch (wc) {
6615
6616                 case 10:
6617                         if(pwlen){
6618                                 /* password, ASCII */
6619                                 CHECK_BYTE_COUNT(pwlen);
6620                                 proto_tree_add_item(tree, hf_smb_password,
6621                                         tvb, offset, pwlen, TRUE);
6622                                 COUNT_BYTES(pwlen);
6623                         }
6624
6625                         break;
6626
6627                 case 13:
6628                         if(apwlen){
6629                                 /* password, ANSI */
6630                                 CHECK_BYTE_COUNT(apwlen);
6631                                 proto_tree_add_item(tree, hf_smb_ansi_password,
6632                                         tvb, offset, apwlen, TRUE);
6633                                 COUNT_BYTES(apwlen);
6634                         }
6635
6636                         if(upwlen){
6637                                 proto_item *item;
6638
6639                                 /* password, Unicode */
6640                                 CHECK_BYTE_COUNT(upwlen);
6641                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
6642                                         tvb, offset, upwlen, TRUE);
6643
6644                                 if (upwlen > 24) {
6645                                         proto_tree *subtree;
6646
6647                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
6648
6649                                         dissect_ntlmv2_response(
6650                                                 tvb, subtree, offset, upwlen);
6651                                 }
6652
6653                                 COUNT_BYTES(upwlen);
6654                         }
6655
6656                         break;
6657                 }
6658
6659                 /* Account Name */
6660                 an = get_unicode_or_ascii_string(tvb, &offset,
6661                         si->unicode, &an_len, FALSE, FALSE, &bc);
6662                 if (an == NULL)
6663                         goto endofcommand;
6664                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
6665                         an);
6666                 COUNT_BYTES(an_len);
6667
6668                 /* Primary domain */
6669                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6670                  * byte in front of this, at least if all the strings are
6671                  * ASCII and the account name is empty. Another bug?
6672                  */
6673                 dn = get_unicode_or_ascii_string(tvb, &offset,
6674                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6675                 if (dn == NULL)
6676                         goto endofcommand;
6677                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6678                         offset, dn_len, dn);
6679                 COUNT_BYTES(dn_len);
6680
6681                 if (check_col(pinfo->cinfo, COL_INFO)) {
6682                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
6683
6684                         if (!dn[0] && !an[0])
6685                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6686                                                 "anonymous");
6687                         else
6688                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6689                                                 "%s\\%s",
6690                                                 format_text(dn, strlen(dn)),
6691                                                 format_text(an, strlen(an)));
6692                 }
6693
6694                 /* OS */
6695                 an = get_unicode_or_ascii_string(tvb, &offset,
6696                         si->unicode, &an_len, FALSE, FALSE, &bc);
6697                 if (an == NULL)
6698                         goto endofcommand;
6699                 proto_tree_add_string(tree, hf_smb_os, tvb,
6700                         offset, an_len, an);
6701                 COUNT_BYTES(an_len);
6702
6703                 /* LANMAN */
6704                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6705                  * padding/null string/whatever in front of this. W2K doesn't
6706                  * appear to. I suspect that's a bug that got fixed; I also
6707                  * suspect that, in practice, nobody ever looks at that field
6708                  * because the bug didn't appear to get fixed until NT 5.0....
6709                  */
6710                 an = get_unicode_or_ascii_string(tvb, &offset,
6711                         si->unicode, &an_len, FALSE, FALSE, &bc);
6712                 if (an == NULL)
6713                         goto endofcommand;
6714                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6715                         offset, an_len, an);
6716                 COUNT_BYTES(an_len);
6717         }
6718
6719         END_OF_SMB
6720
6721         if (cmd != 0xff) {      /* there is an andX command */
6722                 if (andxoffset < offset)
6723                         THROW(ReportedBoundsError);
6724                 pinfo->private_data = si;
6725                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6726         }
6727
6728         return offset;
6729 }
6730
6731 static int
6732 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6733 {
6734         guint8  wc, cmd=0xff;
6735         guint16 andxoffset=0, bc;
6736         guint16 sbloblen=0;
6737         smb_info_t *si = pinfo->private_data;
6738         int an_len;
6739         const char *an;
6740
6741         DISSECTOR_ASSERT(si);
6742
6743         WORD_COUNT;
6744
6745         if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
6746             si->sip->extra_info_type==SMB_EI_UID){
6747                 smb_uid_t *smb_uid;
6748
6749                 smb_uid=si->sip->extra_info;
6750                 smb_uid->logged_in=pinfo->fd->num;
6751                 se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
6752         }
6753
6754         /* next smb command */
6755         cmd = tvb_get_guint8(tvb, offset);
6756         if(cmd!=0xff){
6757                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6758         } else {
6759                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6760         }
6761         offset += 1;
6762
6763         /* reserved byte */
6764         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6765         offset += 1;
6766
6767         /* andxoffset */
6768         andxoffset = tvb_get_letohs(tvb, offset);
6769         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6770         offset += 2;
6771
6772         /* flags */
6773         offset = dissect_setup_action(tvb, tree, offset);
6774
6775         if(wc==4){
6776                 /* security blob length */
6777                 sbloblen = tvb_get_letohs(tvb, offset);
6778                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6779                 offset += 2;
6780         }
6781
6782         BYTE_COUNT;
6783
6784         if(wc==4) {
6785                 proto_item *blob_item;
6786
6787                 /* security blob */
6788                 /* dont try to eat too much of we might get an exception on 
6789                  * short frames and then we will not see anything at all
6790                  * of the security blob.
6791                  */
6792                 if(sbloblen>tvb_length_remaining(tvb,offset)){
6793                         sbloblen=tvb_length_remaining(tvb,offset);
6794                 }
6795                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6796                                                 tvb, offset, sbloblen, TRUE);
6797
6798                 if(sbloblen){
6799                         tvbuff_t *blob_tvb;
6800                         proto_tree *blob_tree;
6801
6802                         blob_tree = proto_item_add_subtree(blob_item, 
6803                                                            ett_smb_secblob);
6804                         CHECK_BYTE_COUNT(sbloblen);
6805
6806                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6807                                                     sbloblen);
6808
6809                         if (si && si->ct && si->ct->raw_ntlmssp && 
6810                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6811                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6812                                          blob_tree);
6813
6814                         }
6815                         else {
6816                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6817                                          blob_tree);
6818
6819                         }
6820
6821                         COUNT_BYTES(sbloblen);
6822                 }
6823         }
6824
6825         /* OS */
6826         an = get_unicode_or_ascii_string(tvb, &offset,
6827                 si->unicode, &an_len, FALSE, FALSE, &bc);
6828         if (an == NULL)
6829                 goto endofcommand;
6830         proto_tree_add_string(tree, hf_smb_os, tvb,
6831                 offset, an_len, an);
6832         COUNT_BYTES(an_len);
6833
6834         /* LANMAN */
6835         an = get_unicode_or_ascii_string(tvb, &offset,
6836                 si->unicode, &an_len, FALSE, FALSE, &bc);
6837         if (an == NULL)
6838                 goto endofcommand;
6839         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6840                 offset, an_len, an);
6841         COUNT_BYTES(an_len);
6842
6843         if((wc==3)||(wc==4)) {
6844                 /* Primary domain */
6845                 an = get_unicode_or_ascii_string(tvb, &offset,
6846                         si->unicode, &an_len, FALSE, FALSE, &bc);
6847                 if (an == NULL)
6848                         goto endofcommand;
6849                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6850                         offset, an_len, an);
6851                 COUNT_BYTES(an_len);
6852         }
6853
6854         END_OF_SMB
6855
6856         if (cmd != 0xff) {      /* there is an andX command */
6857                 if (andxoffset < offset)
6858                         THROW(ReportedBoundsError);
6859                 pinfo->private_data = si;
6860                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6861         }
6862
6863         return offset;
6864 }
6865
6866
6867 static int
6868 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6869 {
6870         guint8  wc, cmd=0xff;
6871         guint16 andxoffset=0;
6872         guint16 bc;
6873
6874         WORD_COUNT;
6875
6876         /* next smb command */
6877         cmd = tvb_get_guint8(tvb, offset);
6878         if(cmd!=0xff){
6879                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6880         } else {
6881                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6882         }
6883         offset += 1;
6884
6885         /* reserved byte */
6886         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6887         offset += 1;
6888
6889         /* andxoffset */
6890         andxoffset = tvb_get_letohs(tvb, offset);
6891         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6892         offset += 2;
6893
6894         BYTE_COUNT;
6895
6896         END_OF_SMB
6897
6898         if (cmd != 0xff) {      /* there is an andX command */
6899                 if (andxoffset < offset)
6900                         THROW(ReportedBoundsError);
6901                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6902         }
6903
6904         return offset;
6905 }
6906
6907
6908 static const true_false_string tfs_connect_support_search = {
6909         "Exclusive search bits supported",
6910         "Exclusive search bits not supported"
6911 };
6912 static const true_false_string tfs_connect_support_in_dfs = {
6913         "Share is in Dfs",
6914         "Share isn't in Dfs"
6915 };
6916
6917 static int
6918 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6919 {
6920         guint16 mask;
6921         proto_item *item = NULL;
6922         proto_tree *tree = NULL;
6923
6924         mask = tvb_get_letohs(tvb, offset);
6925
6926         if(parent_tree){
6927                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6928                         "Optional Support: 0x%04x", mask);
6929                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6930         }
6931
6932         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6933                 tvb, offset, 2, mask);
6934         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6935                 tvb, offset, 2, mask);
6936
6937         offset += 2;
6938
6939         return offset;
6940 }
6941
6942 static const true_false_string tfs_disconnect_tid = {
6943         "DISCONNECT TID",
6944         "Do NOT disconnect TID"
6945 };
6946
6947 static int
6948 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6949 {
6950         guint16 mask;
6951         proto_item *item = NULL;
6952         proto_tree *tree = NULL;
6953
6954         mask = tvb_get_letohs(tvb, offset);
6955
6956         if(parent_tree){
6957                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6958                         "Flags: 0x%04x", mask);
6959                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6960         }
6961
6962         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6963                 tvb, offset, 2, mask);
6964
6965         offset += 2;
6966
6967         return offset;
6968 }
6969
6970 static int
6971 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6972 {
6973         guint8  wc, cmd=0xff;
6974         guint16 bc;
6975         guint16 andxoffset=0, pwlen=0;
6976         smb_info_t *si = pinfo->private_data;
6977         int an_len;
6978         const char *an;
6979
6980         DISSECTOR_ASSERT(si);
6981
6982         WORD_COUNT;
6983
6984         /* next smb command */
6985         cmd = tvb_get_guint8(tvb, offset);
6986         if(cmd!=0xff){
6987                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6988         } else {
6989                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6990         }
6991         offset += 1;
6992
6993         /* reserved byte */
6994         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6995         offset += 1;
6996
6997         /* andxoffset */
6998         andxoffset = tvb_get_letohs(tvb, offset);
6999         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7000         offset += 2;
7001
7002         /* flags */
7003         offset = dissect_connect_flags(tvb, tree, offset);
7004
7005         /* password length*/
7006         pwlen = tvb_get_letohs(tvb, offset);
7007         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7008         offset += 2;
7009
7010         BYTE_COUNT;
7011
7012         /* password */
7013         CHECK_BYTE_COUNT(pwlen);
7014         proto_tree_add_item(tree, hf_smb_password,
7015                 tvb, offset, pwlen, TRUE);
7016         COUNT_BYTES(pwlen);
7017
7018         /* Path */
7019         an = get_unicode_or_ascii_string(tvb, &offset,
7020                 si->unicode, &an_len, FALSE, FALSE, &bc);
7021         if (an == NULL)
7022                 goto endofcommand;
7023         proto_tree_add_string(tree, hf_smb_path, tvb,
7024                 offset, an_len, an);
7025         COUNT_BYTES(an_len);
7026
7027         /* store it for the tid->name/openframe/closeframe matching in
7028          * dissect_smb_tid()   called from the response.
7029          */
7030         if((!pinfo->fd->flags.visited) && si->sip && an){
7031                 si->sip->extra_info_type=SMB_EI_TIDNAME;
7032                 si->sip->extra_info=se_strdup(an);
7033         }
7034
7035         if (check_col(pinfo->cinfo, COL_INFO)) {
7036                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7037                     format_text(an, strlen(an)));
7038         }
7039
7040         /*
7041          * NOTE: the Service string is always ASCII, even if the
7042          * "strings are Unicode" bit is set in the flags2 field
7043          * of the SMB.
7044          */
7045
7046         /* Service */
7047         /* XXX - what if this runs past bc? */
7048         an_len = tvb_strsize(tvb, offset);
7049         CHECK_BYTE_COUNT(an_len);
7050         an = tvb_get_ptr(tvb, offset, an_len);
7051         proto_tree_add_string(tree, hf_smb_service, tvb,
7052                 offset, an_len, an);
7053         COUNT_BYTES(an_len);
7054
7055         END_OF_SMB
7056
7057         if (cmd != 0xff) {      /* there is an andX command */
7058                 if (andxoffset < offset)
7059                         THROW(ReportedBoundsError);
7060                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7061         }
7062
7063         return offset;
7064 }
7065
7066
7067 static int
7068 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7069 {
7070         guint8  wc, wleft, cmd=0xff;
7071         guint16 andxoffset=0;
7072         guint16 bc;
7073         int an_len;
7074         const char *an;
7075         smb_info_t *si = pinfo->private_data;
7076
7077         DISSECTOR_ASSERT(si);
7078
7079         WORD_COUNT;
7080
7081         wleft = wc;     /* this is at least 1 */
7082
7083         /* next smb command */
7084         cmd = tvb_get_guint8(tvb, offset);
7085         if(cmd!=0xff){
7086                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7087         } else {
7088                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7089         }
7090         offset += 1;
7091
7092         /* reserved byte */
7093         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7094         offset += 1;
7095
7096         wleft--;
7097         if (wleft == 0)
7098                 goto bytecount;
7099
7100         /* andxoffset */
7101         andxoffset = tvb_get_letohs(tvb, offset);
7102         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7103         offset += 2;
7104         wleft--;
7105         if (wleft == 0)
7106                 goto bytecount;
7107
7108         /* flags */
7109         offset = dissect_connect_support_bits(tvb, tree, offset);
7110         wleft--;
7111
7112         /* XXX - I've seen captures where this is 7, but I have no
7113            idea how to dissect it.  I'm guessing the third word
7114            contains connect support bits, which looks plausible
7115            from the values I've seen. */
7116
7117         while (wleft != 0) {
7118                 proto_tree_add_text(tree, tvb, offset, 2,
7119                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
7120                 offset += 2;
7121                 wleft--;
7122         }
7123
7124         BYTE_COUNT;
7125
7126         /*
7127          * NOTE: even though the SNIA CIFS spec doesn't say there's
7128          * a "Service" string if there's a word count of 2, the
7129          * document at
7130          *
7131          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7132          *
7133          * (it's in an ugly format - text intended to be sent to a
7134          * printer, with backspaces and overstrikes used for boldfacing
7135          * and underlining; UNIX "col -b" can be used to strip the
7136          * overstrikes out) says there's a "Service" string there, and
7137          * some network traffic has it.
7138          */
7139
7140         /*
7141          * NOTE: the Service string is always ASCII, even if the
7142          * "strings are Unicode" bit is set in the flags2 field
7143          * of the SMB.
7144          */
7145
7146         /* Service */
7147         /* XXX - what if this runs past bc? */
7148         an_len = tvb_strsize(tvb, offset);
7149         CHECK_BYTE_COUNT(an_len);
7150         an = tvb_get_ptr(tvb, offset, an_len);
7151         proto_tree_add_string(tree, hf_smb_service, tvb,
7152                 offset, an_len, an);
7153         COUNT_BYTES(an_len);
7154
7155         /* Now when we know the service type, store it so that we know it for later commands down
7156            this tree */
7157         if(!pinfo->fd->flags.visited){
7158                 /* Remove any previous entry for this TID */
7159                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
7160                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7161                 }
7162                 if(strcmp(an,"IPC") == 0){
7163                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7164                 } else {
7165                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7166                 }
7167         }
7168
7169
7170         if(wc==3){
7171                 if (bc != 0) {
7172                         /*
7173                          * Sometimes this isn't present.
7174                          */
7175
7176                         /* Native FS */
7177                         an = get_unicode_or_ascii_string(tvb, &offset,
7178                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7179                                 &bc);
7180                         if (an == NULL)
7181                                 goto endofcommand;
7182                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7183                                 offset, an_len, an);
7184                         COUNT_BYTES(an_len);
7185                 }
7186         }
7187
7188         END_OF_SMB
7189
7190         if (cmd != 0xff) {      /* there is an andX command */
7191                 if (andxoffset < offset)
7192                         THROW(ReportedBoundsError);
7193                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7194         }
7195
7196         return offset;
7197 }
7198
7199
7200
7201 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7202    NT Transaction command  begins here
7203    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7204 #define NT_TRANS_CREATE         1
7205 #define NT_TRANS_IOCTL          2
7206 #define NT_TRANS_SSD            3
7207 #define NT_TRANS_NOTIFY         4
7208 #define NT_TRANS_RENAME         5
7209 #define NT_TRANS_QSD            6
7210 #define NT_TRANS_GET_USER_QUOTA 7
7211 #define NT_TRANS_SET_USER_QUOTA 8
7212 const value_string nt_cmd_vals[] = {
7213         {NT_TRANS_CREATE,               "NT CREATE"},
7214         {NT_TRANS_IOCTL,                "NT IOCTL"},
7215         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7216         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7217         {NT_TRANS_RENAME,               "NT RENAME"},
7218         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7219         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7220         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7221         {0, NULL}
7222 };
7223
7224 static const value_string nt_ioctl_isfsctl_vals[] = {
7225         {0,     "Device IOCTL"},
7226         {1,     "FS control : FSCTL"},
7227         {0, NULL}
7228 };
7229
7230 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7231 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7232         "Apply the command to share root handle (MUST BE Dfs)",
7233         "Apply to this share",
7234 };
7235
7236 static const value_string nt_notify_action_vals[] = {
7237         {1,     "ADDED (object was added"},
7238         {2,     "REMOVED (object was removed)"},
7239         {3,     "MODIFIED (object was modified)"},
7240         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7241         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7242         {6,     "ADDED_STREAM (a stream was added)"},
7243         {7,     "REMOVED_STREAM (a stream was removed)"},
7244         {8,     "MODIFIED_STREAM (a stream was modified)"},
7245         {0, NULL}
7246 };
7247
7248 static const value_string watch_tree_vals[] = {
7249         {0,     "Current directory only"},
7250         {1,     "Subdirectories also"},
7251         {0, NULL}
7252 };
7253
7254 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7255 #define NT_NOTIFY_STREAM_SIZE   0x00000400
7256 #define NT_NOTIFY_STREAM_NAME   0x00000200
7257 #define NT_NOTIFY_SECURITY      0x00000100
7258 #define NT_NOTIFY_EA            0x00000080
7259 #define NT_NOTIFY_CREATION      0x00000040
7260 #define NT_NOTIFY_LAST_ACCESS   0x00000020
7261 #define NT_NOTIFY_LAST_WRITE    0x00000010
7262 #define NT_NOTIFY_SIZE          0x00000008
7263 #define NT_NOTIFY_ATTRIBUTES    0x00000004
7264 #define NT_NOTIFY_DIR_NAME      0x00000002
7265 #define NT_NOTIFY_FILE_NAME     0x00000001
7266 static const true_false_string tfs_nt_notify_stream_write = {
7267         "Notify on changes to STREAM WRITE",
7268         "Do NOT notify on changes to stream write",
7269 };
7270 static const true_false_string tfs_nt_notify_stream_size = {
7271         "Notify on changes to STREAM SIZE",
7272         "Do NOT notify on changes to stream size",
7273 };
7274 static const true_false_string tfs_nt_notify_stream_name = {
7275         "Notify on changes to STREAM NAME",
7276         "Do NOT notify on changes to stream name",
7277 };
7278 static const true_false_string tfs_nt_notify_security = {
7279         "Notify on changes to SECURITY",
7280         "Do NOT notify on changes to security",
7281 };
7282 static const true_false_string tfs_nt_notify_ea = {
7283         "Notify on changes to EA",
7284         "Do NOT notify on changes to EA",
7285 };
7286 static const true_false_string tfs_nt_notify_creation = {
7287         "Notify on changes to CREATION TIME",
7288         "Do NOT notify on changes to creation time",
7289 };
7290 static const true_false_string tfs_nt_notify_last_access = {
7291         "Notify on changes to LAST ACCESS TIME",
7292         "Do NOT notify on changes to last access time",
7293 };
7294 static const true_false_string tfs_nt_notify_last_write = {
7295         "Notify on changes to LAST WRITE TIME",
7296         "Do NOT notify on changes to last write time",
7297 };
7298 static const true_false_string tfs_nt_notify_size = {
7299         "Notify on changes to SIZE",
7300         "Do NOT notify on changes to size",
7301 };
7302 static const true_false_string tfs_nt_notify_attributes = {
7303         "Notify on changes to ATTRIBUTES",
7304         "Do NOT notify on changes to attributes",
7305 };
7306 static const true_false_string tfs_nt_notify_dir_name = {
7307         "Notify on changes to DIR NAME",
7308         "Do NOT notify on changes to dir name",
7309 };
7310 static const true_false_string tfs_nt_notify_file_name = {
7311         "Notify on changes to FILE NAME",
7312         "Do NOT notify on changes to file name",
7313 };
7314
7315 const value_string create_disposition_vals[] = {
7316         {0,     "Supersede (supersede existing file (if it exists))"},
7317         {1,     "Open (if file exists open it, else fail)"},
7318         {2,     "Create (if file exists fail, else create it)"},
7319         {3,     "Open If (if file exists open it, else create it)"},
7320         {4,     "Overwrite (if file exists overwrite, else fail)"},
7321         {5,     "Overwrite If (if file exists overwrite, else create it)"},
7322         {0, NULL}
7323 };
7324
7325 const value_string impersonation_level_vals[] = {
7326         {0,     "Anonymous"},
7327         {1,     "Identification"},
7328         {2,     "Impersonation"},
7329         {3,     "Delegation"},
7330         {0, NULL}
7331 };
7332
7333 static const true_false_string tfs_nt_security_flags_context_tracking = {
7334         "Security tracking mode is DYNAMIC",
7335         "Security tracking mode is STATIC",
7336 };
7337
7338 static const true_false_string tfs_nt_security_flags_effective_only = {
7339         "ONLY ENABLED aspects of the client's security context are available",
7340         "ALL aspects of the client's security context are available",
7341 };
7342
7343 static const true_false_string tfs_nt_create_bits_oplock = {
7344         "Requesting OPLOCK",
7345         "Does NOT request oplock"
7346 };
7347
7348 static const true_false_string tfs_nt_create_bits_boplock = {
7349         "Requesting BATCH OPLOCK",
7350         "Does NOT request batch oplock"
7351 };
7352
7353 /*
7354  * XXX - must be a directory, and can be a file, or can be a directory,
7355  * and must be a file?
7356  */
7357 static const true_false_string tfs_nt_create_bits_dir = {
7358         "Target of open MUST be a DIRECTORY",
7359         "Target of open can be a file"
7360 };
7361
7362 static const true_false_string tfs_nt_create_bits_ext_resp = {
7363   "Extended responses required",
7364   "Extended responses NOT required"
7365 };
7366
7367 static const true_false_string tfs_nt_access_mask_generic_read = {
7368         "GENERIC READ is set",
7369         "Generic read is NOT set"
7370 };
7371 static const true_false_string tfs_nt_access_mask_generic_write = {
7372         "GENERIC WRITE is set",
7373         "Generic write is NOT set"
7374 };
7375 static const true_false_string tfs_nt_access_mask_generic_execute = {
7376         "GENERIC EXECUTE is set",
7377         "Generic execute is NOT set"
7378 };
7379 static const true_false_string tfs_nt_access_mask_generic_all = {
7380         "GENERIC ALL is set",
7381         "Generic all is NOT set"
7382 };
7383 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
7384         "MAXIMUM ALLOWED is set",
7385         "Maximum allowed is NOT set"
7386 };
7387 static const true_false_string tfs_nt_access_mask_system_security = {
7388         "SYSTEM SECURITY is set",
7389         "System security is NOT set"
7390 };
7391 static const true_false_string tfs_nt_access_mask_synchronize = {
7392         "Can wait on handle to SYNCHRONIZE on completion of I/O",
7393         "Can NOT wait on handle to synchronize on completion of I/O"
7394 };
7395 static const true_false_string tfs_nt_access_mask_write_owner = {
7396         "Can WRITE OWNER (take ownership)",
7397         "Can NOT write owner (take ownership)"
7398 };
7399 static const true_false_string tfs_nt_access_mask_write_dac = {
7400         "OWNER may WRITE the DAC",
7401         "Owner may NOT write to the DAC"
7402 };
7403 static const true_false_string tfs_nt_access_mask_read_control = {
7404         "READ ACCESS to owner, group and ACL of the SID",
7405         "Read access is NOT granted to owner, group and ACL of the SID"
7406 };
7407 static const true_false_string tfs_nt_access_mask_delete = {
7408         "DELETE access",
7409         "NO delete access"
7410 };
7411 static const true_false_string tfs_nt_access_mask_write_attributes = {
7412         "WRITE ATTRIBUTES access",
7413         "NO write attributes access"
7414 };
7415 static const true_false_string tfs_nt_access_mask_read_attributes = {
7416         "READ ATTRIBUTES access",
7417         "NO read attributes access"
7418 };
7419 static const true_false_string tfs_nt_access_mask_delete_child = {
7420         "DELETE CHILD access",
7421         "NO delete child access"
7422 };
7423 static const true_false_string tfs_nt_access_mask_execute = {
7424         "EXECUTE access",
7425         "NO execute access"
7426 };
7427 static const true_false_string tfs_nt_access_mask_write_ea = {
7428         "WRITE EXTENDED ATTRIBUTES access",
7429         "NO write extended attributes access"
7430 };
7431 static const true_false_string tfs_nt_access_mask_read_ea = {
7432         "READ EXTENDED ATTRIBUTES access",
7433         "NO read extended attributes access"
7434 };
7435 static const true_false_string tfs_nt_access_mask_append = {
7436         "APPEND access",
7437         "NO append access"
7438 };
7439 static const true_false_string tfs_nt_access_mask_write = {
7440         "WRITE access",
7441         "NO write access"
7442 };
7443 static const true_false_string tfs_nt_access_mask_read = {
7444         "READ access",
7445         "NO read access"
7446 };
7447
7448 static const true_false_string tfs_nt_share_access_delete = {
7449         "Object can be shared for DELETE",
7450         "Object can NOT be shared for delete"
7451 };
7452 static const true_false_string tfs_nt_share_access_write = {
7453         "Object can be shared for WRITE",
7454         "Object can NOT be shared for write"
7455 };
7456 static const true_false_string tfs_nt_share_access_read = {
7457         "Object can be shared for READ",
7458         "Object can NOT be shared for read"
7459 };
7460
7461 static const value_string oplock_level_vals[] = {
7462         {0,     "No oplock granted"},
7463         {1,     "Exclusive oplock granted"},
7464         {2,     "Batch oplock granted"},
7465         {3,     "Level II oplock granted"},
7466         {0, NULL}
7467 };
7468
7469 static const value_string device_type_vals[] = {
7470         {0x00000001,    "Beep"},
7471         {0x00000002,    "CDROM"},
7472         {0x00000003,    "CDROM Filesystem"},
7473         {0x00000004,    "Controller"},
7474         {0x00000005,    "Datalink"},
7475         {0x00000006,    "Dfs"},
7476         {0x00000007,    "Disk"},
7477         {0x00000008,    "Disk Filesystem"},
7478         {0x00000009,    "Filesystem"},
7479         {0x0000000a,    "Inport Port"},
7480         {0x0000000b,    "Keyboard"},
7481         {0x0000000c,    "Mailslot"},
7482         {0x0000000d,    "MIDI-In"},
7483         {0x0000000e,    "MIDI-Out"},
7484         {0x0000000f,    "Mouse"},
7485         {0x00000010,    "Multi UNC Provider"},
7486         {0x00000011,    "Named Pipe"},
7487         {0x00000012,    "Network"},
7488         {0x00000013,    "Network Browser"},
7489         {0x00000014,    "Network Filesystem"},
7490         {0x00000015,    "NULL"},
7491         {0x00000016,    "Parallel Port"},
7492         {0x00000017,    "Physical card"},
7493         {0x00000018,    "Printer"},
7494         {0x00000019,    "Scanner"},
7495         {0x0000001a,    "Serial Mouse port"},
7496         {0x0000001b,    "Serial port"},
7497         {0x0000001c,    "Screen"},
7498         {0x0000001d,    "Sound"},
7499         {0x0000001e,    "Streams"},
7500         {0x0000001f,    "Tape"},
7501         {0x00000020,    "Tape Filesystem"},
7502         {0x00000021,    "Transport"},
7503         {0x00000022,    "Unknown"},
7504         {0x00000023,    "Video"},
7505         {0x00000024,    "Virtual Disk"},
7506         {0x00000025,    "WAVE-In"},
7507         {0x00000026,    "WAVE-Out"},
7508         {0x00000027,    "8042 Port"},
7509         {0x00000028,    "Network Redirector"},
7510         {0x00000029,    "Battery"},
7511         {0x0000002a,    "Bus Extender"},
7512         {0x0000002b,    "Modem"},
7513         {0x0000002c,    "VDM"},
7514         {0,     NULL}
7515 };
7516
7517 static const value_string is_directory_vals[] = {
7518         {0,     "This is NOT a directory"},
7519         {1,     "This is a DIRECTORY"},
7520         {0, NULL}
7521 };
7522
7523 typedef struct _nt_trans_data {
7524         int subcmd;
7525         guint32 sd_len;
7526         guint32 ea_len;
7527 } nt_trans_data;
7528
7529
7530
7531 static int
7532 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7533 {
7534         guint8 mask;
7535         proto_item *item = NULL;
7536         proto_tree *tree = NULL;
7537
7538         mask = tvb_get_guint8(tvb, offset);
7539
7540         if(parent_tree){
7541                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7542                         "Security Flags: 0x%02x", mask);
7543                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
7544         }
7545
7546         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
7547                 tvb, offset, 1, mask);
7548         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
7549                 tvb, offset, 1, mask);
7550
7551         offset += 1;
7552
7553         return offset;
7554 }
7555
7556 /*
7557  * XXX - there are some more flags in the description of "ZwOpenFile()"
7558  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7559  * the wire as well?  (The spec at
7560  *
7561  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7562  *
7563  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7564  * via the SMB protocol.  The NT redirector should convert this option
7565  * to FILE_WRITE_THROUGH."
7566  *
7567  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7568  * values one would infer from their position in the list of flags for
7569  * "ZwOpenFile()".  Most of the others probably have those values
7570  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7571  * which might go over the wire (for the benefit of backup/restore software).
7572  */
7573 static const true_false_string tfs_nt_create_options_directory = {
7574         "File being created/opened must be a directory",
7575         "File being created/opened must not be a directory"
7576 };
7577 static const true_false_string tfs_nt_create_options_write_through = {
7578         "Writes should flush buffered data before completing",
7579         "Writes need not flush buffered data before completing"
7580 };
7581 static const true_false_string tfs_nt_create_options_sequential_only = {
7582         "The file will only be accessed sequentially",
7583         "The file might not only be accessed sequentially"
7584 };
7585 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
7586         "NO intermediate buffering is allowed",
7587         "Intermediate buffering is allowed"
7588 };
7589 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7590         "All operations SYNCHRONOUS, waits subject to termination from alert",
7591         "Operations NOT necessarily synchronous"
7592 };
7593 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7594         "All operations SYNCHRONOUS, waits not subject to alert",
7595         "Operations NOT necessarily synchronous"
7596 };
7597 static const true_false_string tfs_nt_create_options_non_directory = {
7598         "File being created/opened must not be a directory",
7599         "File being created/opened must be a directory"
7600 };
7601 static const true_false_string tfs_nt_create_options_create_tree_connection = {
7602         "Create Tree Connections is SET",
7603         "Create Tree Connections is NOT set"
7604 };
7605 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
7606         "Complete if oplocked is SET",
7607         "Complete if oplocked is NOT set"
7608 };
7609 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7610         "The client does not understand extended attributes",
7611         "The client understands extended attributes"
7612 };
7613 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7614         "The client understands only 8.3 file names",
7615         "The client understands long file names"
7616 };
7617 static const true_false_string tfs_nt_create_options_random_access = {
7618         "The file will be accessed randomly",
7619         "The file will not be accessed randomly"
7620 };
7621 static const true_false_string tfs_nt_create_options_delete_on_close = {
7622         "The file should be deleted when it is closed",
7623         "The file should not be deleted when it is closed"
7624 };
7625 static const true_false_string tfs_nt_create_options_open_by_fileid = {
7626         "OpenByFileID bit is SET",
7627         "OpenByFileID is NOT set"
7628 };
7629 static const true_false_string tfs_nt_create_options_backup_intent = {
7630         "This is a create with BACKUP INTENT",
7631         "This is a normal create"
7632 };
7633 static const true_false_string tfs_nt_create_options_no_compression = {
7634         "Open/Create with NO Compression",
7635         "Compression is allowed for Open/Create"
7636 };
7637 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
7638         "Reserve Opfilter is SET",
7639         "Reserve Opfilter is NOT set"
7640 };
7641 static const true_false_string tfs_nt_create_options_open_reparse_point = {
7642         "Open a Reparse Point",
7643         "Normal open"
7644 };
7645 static const true_false_string tfs_nt_create_options_open_no_recall = {
7646         "Open No Recall is SET",
7647         "Open no recall is NOT set"
7648 };
7649 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
7650         "This is an OPEN FOR FREE SPACE QUERY",
7651         "This is NOT an open for free space query"
7652 };
7653
7654 int
7655 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7656 {
7657         guint32 mask;
7658         proto_item *item = NULL;
7659         proto_tree *tree = NULL;
7660
7661         mask = tvb_get_letohl(tvb, offset);
7662
7663         if(parent_tree){
7664                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7665                         "Completion Filter: 0x%08x", mask);
7666                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7667         }
7668
7669         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7670                 tvb, offset, 4, mask);
7671         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7672                 tvb, offset, 4, mask);
7673         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7674                 tvb, offset, 4, mask);
7675         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7676                 tvb, offset, 4, mask);
7677         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7678                 tvb, offset, 4, mask);
7679         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7680                 tvb, offset, 4, mask);
7681         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7682                 tvb, offset, 4, mask);
7683         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7684                 tvb, offset, 4, mask);
7685         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7686                 tvb, offset, 4, mask);
7687         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7688                 tvb, offset, 4, mask);
7689         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7690                 tvb, offset, 4, mask);
7691         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7692                 tvb, offset, 4, mask);
7693
7694         offset += 4;
7695         return offset;
7696 }
7697
7698 static int
7699 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7700 {
7701         guint8 mask;
7702         proto_item *item = NULL;
7703         proto_tree *tree = NULL;
7704
7705         mask = tvb_get_guint8(tvb, offset);
7706
7707         if(parent_tree){
7708                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7709                         "Completion Filter: 0x%02x", mask);
7710                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7711         }
7712
7713         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7714                 tvb, offset, 1, mask);
7715
7716         offset += 1;
7717         return offset;
7718 }
7719
7720 /*
7721  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7722  * Native API Reference".
7723  */
7724 static const true_false_string tfs_nt_qsd_owner = {
7725         "Requesting OWNER security information",
7726         "NOT requesting owner security information",
7727 };
7728
7729 static const true_false_string tfs_nt_qsd_group = {
7730         "Requesting GROUP security information",
7731         "NOT requesting group security information",
7732 };
7733
7734 static const true_false_string tfs_nt_qsd_dacl = {
7735         "Requesting DACL security information",
7736         "NOT requesting DACL security information",
7737 };
7738
7739 static const true_false_string tfs_nt_qsd_sacl = {
7740         "Requesting SACL security information",
7741         "NOT requesting SACL security information",
7742 };
7743
7744 #define NT_QSD_OWNER    0x00000001
7745 #define NT_QSD_GROUP    0x00000002
7746 #define NT_QSD_DACL     0x00000004
7747 #define NT_QSD_SACL     0x00000008
7748
7749 int
7750 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7751 {
7752         guint32 mask;
7753         proto_item *item = NULL;
7754         proto_tree *tree = NULL;
7755
7756         mask = tvb_get_letohl(tvb, offset);
7757
7758         if(parent_tree){
7759                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7760                         "Security Information: 0x%08x", mask);
7761                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7762         }
7763
7764         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7765                 tvb, offset, 4, mask);
7766         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7767                 tvb, offset, 4, mask);
7768         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7769                 tvb, offset, 4, mask);
7770         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7771                 tvb, offset, 4, mask);
7772
7773         offset += 4;
7774
7775         return offset;
7776 }
7777
7778 static int
7779 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7780 {
7781         int old_offset, old_sid_offset;
7782         guint32 qsize;
7783
7784         do {
7785                 old_offset=offset;
7786
7787                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7788                 qsize=tvb_get_letohl(tvb, offset);
7789                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7790                 COUNT_BYTES_TRANS_SUBR(4);
7791
7792                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7793                 /* length of SID */
7794                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7795                 COUNT_BYTES_TRANS_SUBR(4);
7796
7797                 /* 16 unknown bytes */
7798                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7799                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7800                             offset, 8, TRUE);
7801                 COUNT_BYTES_TRANS_SUBR(8);
7802
7803                 /* number of bytes for used quota */
7804                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7805                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7806                 COUNT_BYTES_TRANS_SUBR(8);
7807
7808                 /* number of bytes for quota warning */
7809                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7810                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7811                 COUNT_BYTES_TRANS_SUBR(8);
7812
7813                 /* number of bytes for quota limit */
7814                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7815                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7816                 COUNT_BYTES_TRANS_SUBR(8);
7817
7818                 /* SID of the user */
7819                 old_sid_offset=offset;
7820                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7821                 *bcp -= (offset-old_sid_offset);
7822
7823                 if(qsize){
7824                         offset = old_offset+qsize;
7825                 }
7826         }while(qsize);
7827
7828
7829         return offset;
7830 }
7831
7832
7833 static int
7834 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)
7835 {
7836         proto_item *item = NULL;
7837         proto_tree *tree = NULL;
7838         smb_info_t *si;
7839         int old_offset = offset;
7840         guint16 bcp=bc; /* XXX fixme */
7841         struct access_mask_info *ami=NULL;
7842         tvbuff_t *ioctl_tvb;
7843
7844         si = (smb_info_t *)pinfo->private_data;
7845
7846         DISSECTOR_ASSERT(si);
7847
7848         if(parent_tree){
7849                 tvb_ensure_bytes_exist(tvb, offset, bc);
7850                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7851                                 "%s Data",
7852                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7853                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7854         }
7855
7856         switch(ntd->subcmd){
7857         case NT_TRANS_CREATE:
7858                 /* security descriptor */
7859                 if(ntd->sd_len){
7860                         offset = dissect_nt_sec_desc(
7861                                 tvb, offset, pinfo, tree, NULL, TRUE,
7862                                 ntd->sd_len, NULL);
7863                 }
7864
7865                 /* extended attributes */
7866                 if(ntd->ea_len){
7867                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7868                         offset += ntd->ea_len;
7869                 }
7870
7871                 break;
7872         case NT_TRANS_IOCTL:
7873                 /* ioctl data */
7874                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
7875                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
7876
7877
7878                 offset += bc;
7879
7880                 break;
7881         case NT_TRANS_SSD:
7882                 if(nti){
7883                         switch(nti->fid_type){
7884                         case SMB_FID_TYPE_FILE:
7885                                 ami= &smb_file_access_mask_info;
7886                                 break;
7887                         case SMB_FID_TYPE_DIR:
7888                                 ami= &smb_dir_access_mask_info;
7889                                 break;
7890                         }
7891                 }
7892
7893                 offset = dissect_nt_sec_desc(
7894                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
7895                 break;
7896         case NT_TRANS_NOTIFY:
7897                 break;
7898         case NT_TRANS_RENAME:
7899                 /* XXX not documented */
7900                 break;
7901         case NT_TRANS_QSD:
7902                 break;
7903         case NT_TRANS_GET_USER_QUOTA:
7904                 /* unknown 4 bytes */
7905                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7906                             offset, 4, TRUE);
7907                 offset += 4;
7908
7909                 /* length of SID */
7910                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7911                 offset +=4;
7912
7913                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7914                 break;
7915         case NT_TRANS_SET_USER_QUOTA:
7916                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7917                 break;
7918         }
7919
7920         /* ooops there were data we didnt know how to process */
7921         if((offset-old_offset) < bc){
7922                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7923                     bc - (offset-old_offset), TRUE);
7924                 offset += bc - (offset-old_offset);
7925         }
7926
7927         return offset;
7928 }
7929
7930 static int
7931 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)
7932 {
7933         proto_item *item = NULL;
7934         proto_tree *tree = NULL;
7935         smb_info_t *si;
7936         guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options;
7937         const char *fn;
7938
7939         si = (smb_info_t *)pinfo->private_data;
7940
7941         DISSECTOR_ASSERT(si);
7942
7943         if(parent_tree){
7944                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7945                                 "%s Parameters",
7946                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7947                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7948         }
7949
7950         switch(ntd->subcmd){
7951         case NT_TRANS_CREATE:
7952                 /* Create flags */
7953                 create_flags=tvb_get_letohl(tvb, offset);
7954                 offset = dissect_nt_create_bits(tvb, tree, offset, create_flags);
7955                 bc -= 4;
7956
7957                 /* root directory fid */
7958                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7959                 COUNT_BYTES(4);
7960
7961                 /* nt access mask */
7962                 access_mask=tvb_get_letohl(tvb, offset);
7963                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, access_mask);
7964                 bc -= 4;
7965
7966                 /* allocation size */
7967                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7968                 COUNT_BYTES(8);
7969
7970                 /* Extended File Attributes */
7971                 file_attributes=tvb_get_letohl(tvb, offset);
7972                 offset = dissect_file_ext_attr_bits(tvb, tree, offset, file_attributes);
7973                 bc -= 4;
7974
7975                 /* share access */
7976                 share_access=tvb_get_letohl(tvb, offset);
7977                 offset = dissect_nt_share_access_bits(tvb, tree, offset, share_access);
7978                 bc -= 4;
7979
7980                 /* create disposition */
7981                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7982                 COUNT_BYTES(4);
7983
7984                 /* create options */
7985                 create_options=tvb_get_letohl(tvb, offset);
7986                 offset = dissect_nt_create_options_bits(tvb, tree, offset, create_options);
7987                 bc -= 4;
7988
7989                 /* sd length */
7990                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7991                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7992                 COUNT_BYTES(4);
7993
7994                 /* ea length */
7995                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7996                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
7997                 COUNT_BYTES(4);
7998
7999                 /* file name len */
8000                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8001                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8002                 COUNT_BYTES(4);
8003
8004                 /* impersonation level */
8005                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8006                 COUNT_BYTES(4);
8007
8008                 /* security flags */
8009                 offset = dissect_nt_security_flags(tvb, tree, offset);
8010                 bc -= 1;
8011
8012                 /* file name */
8013                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8014                 if (fn != NULL) {
8015                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8016                                 fn);
8017                         COUNT_BYTES(fn_len);
8018                 }
8019
8020                 break;
8021         case NT_TRANS_IOCTL:
8022                 break;
8023         case NT_TRANS_SSD: {
8024                 guint16 fid;
8025                 smb_fid_info_t *fid_info;
8026
8027                 /* fid */
8028                 fid = tvb_get_letohs(tvb, offset);
8029                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8030                 offset += 2;
8031                 if(nti){
8032                         if(fid_info){
8033                                 nti->fid_type=fid_info->type;
8034                         } else {
8035                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8036                         }
8037                 }
8038
8039                 /* 2 reserved bytes */
8040                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8041                 offset += 2;
8042
8043                 /* security information */
8044                 offset = dissect_security_information_mask(tvb, tree, offset);
8045                 break;
8046         }
8047         case NT_TRANS_NOTIFY:
8048                 break;
8049         case NT_TRANS_RENAME:
8050                 /* XXX not documented */
8051                 break;
8052         case NT_TRANS_QSD: {
8053                 guint16 fid;
8054                 smb_fid_info_t *fid_info;
8055
8056                 /* fid */
8057                 fid = tvb_get_letohs(tvb, offset);
8058                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8059                 offset += 2;
8060                 if(nti){
8061                         if(fid_info){
8062                                 nti->fid_type=fid_info->type;
8063                         } else {
8064                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8065                         }
8066                 }
8067
8068                 /* 2 reserved bytes */
8069                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8070                 offset += 2;
8071
8072                 /* security information */
8073                 offset = dissect_security_information_mask(tvb, tree, offset);
8074                 break;
8075         }
8076         case NT_TRANS_GET_USER_QUOTA:
8077                 /* not decoded yet */
8078                 break;
8079         case NT_TRANS_SET_USER_QUOTA:
8080                 /* not decoded yet */
8081                 break;
8082         }
8083
8084         return offset;
8085 }
8086
8087 static int
8088 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8089 {
8090         proto_item *item = NULL;
8091         proto_tree *tree = NULL;
8092         int old_offset = offset;
8093         smb_info_t *si;
8094         smb_nt_transact_info_t *nti;
8095         smb_saved_info_t *sip;
8096
8097
8098         si = (smb_info_t *)pinfo->private_data;
8099         DISSECTOR_ASSERT(si);
8100         sip = si->sip;
8101         DISSECTOR_ASSERT(sip);
8102         nti=sip->extra_info;
8103
8104
8105         if(parent_tree){
8106                 tvb_ensure_bytes_exist(tvb, offset, len);
8107                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8108                                 "%s Setup",
8109                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8110                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8111         }
8112
8113         switch(ntd->subcmd){
8114         case NT_TRANS_CREATE:
8115                 break;
8116         case NT_TRANS_IOCTL: {
8117                 guint16 fid;
8118
8119                 /* function code */
8120                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
8121
8122                 /* fid */
8123                 fid = tvb_get_letohs(tvb, offset);
8124                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8125                 offset += 2;
8126
8127                 /* isfsctl */
8128                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8129                 offset += 1;
8130
8131                 /* isflags */
8132                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8133
8134                 break;
8135         }
8136         case NT_TRANS_SSD:
8137                 break;
8138         case NT_TRANS_NOTIFY: {
8139                 guint16 fid;
8140
8141                 /* completion filter */
8142                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8143
8144                 /* fid */
8145                 fid = tvb_get_letohs(tvb, offset);
8146                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8147                 offset += 2;
8148
8149                 /* watch tree */
8150                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8151                 offset += 1;
8152
8153                 /* reserved byte */
8154                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8155                 offset += 1;
8156
8157                 break;
8158         }
8159         case NT_TRANS_RENAME:
8160                 /* XXX not documented */
8161                 break;
8162         case NT_TRANS_QSD:
8163                 break;
8164         case NT_TRANS_GET_USER_QUOTA:
8165                 /* not decoded yet */
8166                 break;
8167         case NT_TRANS_SET_USER_QUOTA:
8168                 /* not decoded yet */
8169                 break;
8170         }
8171
8172         return old_offset+len;
8173 }
8174
8175
8176 static int
8177 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8178 {
8179         guint8 wc, sc;
8180         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8181         smb_info_t *si;
8182         smb_saved_info_t *sip;
8183         int subcmd;
8184         nt_trans_data ntd;
8185         guint16 bc;
8186         guint32 padcnt;
8187         smb_nt_transact_info_t *nti=NULL;
8188
8189         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8190
8191         si = (smb_info_t *)pinfo->private_data;
8192         DISSECTOR_ASSERT(si);
8193         sip = si->sip;
8194
8195         WORD_COUNT;
8196
8197         if(wc>=19){
8198                 /* primary request */
8199                 /* max setup count */
8200                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8201                 offset += 1;
8202
8203                 /* 2 reserved bytes */
8204                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8205                 offset += 2;
8206         } else {
8207                 /* secondary request */
8208                 /* 3 reserved bytes */
8209                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8210                 offset += 3;
8211         }
8212
8213
8214         /* total param count */
8215         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8216         offset += 4;
8217
8218         /* total data count */
8219         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8220         offset += 4;
8221
8222         if(wc>=19){
8223                 /* primary request */
8224                 /* max param count */
8225                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8226                 offset += 4;
8227
8228                 /* max data count */
8229                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8230                 offset += 4;
8231         }
8232
8233         /* param count */
8234         pc = tvb_get_letohl(tvb, offset);
8235         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8236         offset += 4;
8237
8238         /* param offset */
8239         po = tvb_get_letohl(tvb, offset);
8240         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8241         offset += 4;
8242
8243         /* param displacement */
8244         if(wc>=19){
8245                 /* primary request*/
8246                 pd = 0;
8247         } else {
8248                 /* secondary request */
8249                 pd = tvb_get_letohl(tvb, offset);
8250                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8251                 offset += 4;
8252         }
8253
8254         /* data count */
8255         dc = tvb_get_letohl(tvb, offset);
8256         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8257         offset += 4;
8258
8259         /* data offset */
8260         od = tvb_get_letohl(tvb, offset);
8261         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8262         offset += 4;
8263
8264         /* data displacement */
8265         if(wc>=19){
8266                 /* primary request */
8267                 dd = 0;
8268         } else {
8269                 /* secondary request */
8270                 dd = tvb_get_letohl(tvb, offset);
8271                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8272                 offset += 4;
8273         }
8274
8275         /* setup count */
8276         if(wc>=19){
8277                 /* primary request */
8278                 sc = tvb_get_guint8(tvb, offset);
8279                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8280                 offset += 1;
8281         } else {
8282                 /* secondary request */
8283                 sc = 0;
8284         }
8285
8286         /* function */
8287         if(wc>=19){
8288                 /* primary request */
8289                 subcmd = tvb_get_letohs(tvb, offset);
8290                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8291                 if(check_col(pinfo->cinfo, COL_INFO)){
8292                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8293                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8294                 }
8295                 ntd.subcmd = subcmd;
8296                 if (!si->unidir && sip) {
8297                         if(!pinfo->fd->flags.visited){
8298                                 /*
8299                                  * Allocate a new smb_nt_transact_info_t
8300                                  * structure.
8301                                  */
8302                                 nti = se_alloc(sizeof(smb_nt_transact_info_t));
8303                                 nti->subcmd = subcmd;
8304                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8305                                 sip->extra_info = nti;
8306                                 sip->extra_info_type = SMB_EI_NTI;
8307                         } else {
8308                                 if(sip->extra_info_type == SMB_EI_NTI){
8309                                         nti=sip->extra_info;
8310                                 }
8311                         }
8312                 }
8313         } else {
8314                 /* secondary request */
8315                 if(check_col(pinfo->cinfo, COL_INFO)){
8316                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8317                 }
8318         }
8319         offset += 2;
8320
8321         /* this is a padding byte */
8322         if(offset%1){
8323                 /* pad byte */
8324                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8325                 offset += 1;
8326         }
8327
8328         /* if there were any setup bytes, decode them */
8329         if(sc){
8330                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8331                 offset += sc*2;
8332         }
8333
8334         BYTE_COUNT;
8335
8336         /* parameters */
8337         if(po>(guint32)offset){
8338                 /* We have some initial padding bytes.
8339                 */
8340                 padcnt = po-offset;
8341                 if (padcnt > bc)
8342                         padcnt = bc;
8343                 CHECK_BYTE_COUNT(padcnt);
8344                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8345                 COUNT_BYTES(padcnt);
8346         }
8347         if(pc){
8348                 CHECK_BYTE_COUNT(pc);
8349                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti);
8350                 COUNT_BYTES(pc);
8351         }
8352
8353         /* data */
8354         if(od>(guint32)offset){
8355                 /* We have some initial padding bytes.
8356                 */
8357                 padcnt = od-offset;
8358                 if (padcnt > bc)
8359                         padcnt = bc;
8360                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8361                 COUNT_BYTES(padcnt);
8362         }
8363         if(dc){
8364                 CHECK_BYTE_COUNT(dc);
8365                 dissect_nt_trans_data_request(
8366                         tvb, pinfo, offset, tree, dc, &ntd, nti);
8367                 COUNT_BYTES(dc);
8368         }
8369
8370         END_OF_SMB
8371
8372         return offset;
8373 }
8374
8375
8376
8377 static int
8378 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8379                                int offset, proto_tree *parent_tree, int len,
8380                                nt_trans_data *ntd _U_,
8381                                smb_nt_transact_info_t *nti)
8382 {
8383         proto_item *item = NULL;
8384         proto_tree *tree = NULL;
8385         smb_info_t *si;
8386         guint16 bcp;
8387         struct access_mask_info *ami=NULL;
8388         tvbuff_t *ioctl_tvb;
8389
8390         si = (smb_info_t *)pinfo->private_data;
8391         DISSECTOR_ASSERT(si);
8392
8393         if(parent_tree){
8394                 tvb_ensure_bytes_exist(tvb, offset, len);
8395                 if(nti != NULL){
8396                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8397                                 "%s Data",
8398                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8399                 } else {
8400                         /*
8401                          * We never saw the request to which this is a
8402                          * response.
8403                          */
8404                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8405                                 "Unknown NT Transaction Data (matching request not seen)");
8406                 }
8407                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8408         }
8409
8410         if (nti == NULL) {
8411                 offset += len;
8412                 return offset;
8413         }
8414         switch(nti->subcmd){
8415         case NT_TRANS_CREATE:
8416                 break;
8417         case NT_TRANS_IOCTL:
8418                 /* ioctl data */
8419                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
8420                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
8421
8422                 offset += len;
8423
8424                 break;
8425         case NT_TRANS_SSD:
8426                 break;
8427         case NT_TRANS_NOTIFY:
8428                 break;
8429         case NT_TRANS_RENAME:
8430                 /* XXX not documented */
8431                 break;
8432         case NT_TRANS_QSD:
8433                 if(nti){
8434                         switch(nti->fid_type){
8435                         case SMB_FID_TYPE_FILE:
8436                                 ami= &smb_file_access_mask_info;
8437                                 break;
8438                         case SMB_FID_TYPE_DIR:
8439                                 ami= &smb_dir_access_mask_info;
8440                                 break;
8441                         }
8442                 }
8443                 offset = dissect_nt_sec_desc(
8444                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
8445                 break;
8446         case NT_TRANS_GET_USER_QUOTA:
8447                 bcp=len;
8448                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8449                 break;
8450         case NT_TRANS_SET_USER_QUOTA:
8451                 /* not decoded yet */
8452                 break;
8453         }
8454
8455         return offset;
8456 }
8457
8458 static int
8459 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8460                                 int offset, proto_tree *parent_tree,
8461                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8462 {
8463         proto_item *item = NULL;
8464         proto_tree *tree = NULL;
8465         guint32 fn_len;
8466         const char *fn;
8467         smb_info_t *si;
8468         smb_nt_transact_info_t *nti;
8469         guint16 fid;
8470         int old_offset;
8471         guint32 neo;
8472         int padcnt;
8473         smb_fid_info_t *fid_info=NULL;
8474         guint16 ftype;
8475         guint8  isdir;
8476
8477         si = (smb_info_t *)pinfo->private_data;
8478         DISSECTOR_ASSERT(si);
8479
8480         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8481                 nti = si->sip->extra_info;
8482         else
8483                 nti = NULL;
8484
8485         if(parent_tree){
8486                 tvb_ensure_bytes_exist(tvb, offset, len);
8487                 if(nti != NULL){
8488                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8489                                 "%s Parameters",
8490                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8491                 } else {
8492                         /*
8493                          * We never saw the request to which this is a
8494                          * response.
8495                          */
8496                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8497                                 "Unknown NT Transaction Parameters (matching request not seen)");
8498                 }
8499                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8500         }
8501
8502         if (nti == NULL) {
8503                 offset += len;
8504                 return offset;
8505         }
8506         switch(nti->subcmd){
8507         case NT_TRANS_CREATE:
8508                 /* oplock level */
8509                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8510                 offset += 1;
8511
8512                 /* reserved byte */
8513                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8514                 offset += 1;
8515
8516                 /* fid */
8517                 fid = tvb_get_letohs(tvb, offset);
8518                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
8519                 offset += 2;
8520
8521                 /* create action */
8522                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8523                 offset += 4;
8524
8525                 /* ea error offset */
8526                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8527                 offset += 4;
8528
8529                 /* create time */
8530                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8531                         hf_smb_create_time);
8532
8533                 /* access time */
8534                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8535                         hf_smb_access_time);
8536
8537                 /* last write time */
8538                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8539                         hf_smb_last_write_time);
8540
8541                 /* last change time */
8542                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8543                         hf_smb_change_time);
8544
8545                 /* Extended File Attributes */
8546                 offset = dissect_file_ext_attr(tvb, tree, offset);
8547
8548                 /* allocation size */
8549                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8550                 offset += 8;
8551
8552                 /* end of file */
8553                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8554                 offset += 8;
8555
8556                 /* File Type */
8557                 ftype=tvb_get_letohs(tvb, offset);
8558                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8559                 offset += 2;
8560
8561                 /* device state */
8562                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8563
8564                 /* is directory */
8565                 isdir=tvb_get_guint8(tvb, offset);
8566                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8567                 offset += 1;
8568
8569                 /* Try to remember the type of this fid so that we can dissect
8570                  * any future security descriptor (access mask) properly
8571                  */
8572                 if(ftype==0){
8573                         if(isdir==0){
8574                                 if(fid_info){
8575                                         fid_info->type=SMB_FID_TYPE_FILE;
8576                                 }
8577                         } else {
8578                                 if(fid_info){
8579                                         fid_info->type=SMB_FID_TYPE_DIR;
8580                                 }
8581                         }
8582                 }
8583                 if(ftype==2){
8584                         if(fid_info){
8585                                 fid_info->type=SMB_FID_TYPE_PIPE;
8586                         }
8587                 }               
8588                 break;
8589         case NT_TRANS_IOCTL:
8590                 break;
8591         case NT_TRANS_SSD:
8592                 break;
8593         case NT_TRANS_NOTIFY:
8594                 while(len){
8595                         old_offset = offset;
8596
8597                         /* next entry offset */
8598                         neo = tvb_get_letohl(tvb, offset);
8599                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8600                         COUNT_BYTES(4);
8601                         len -= 4;
8602                         /* broken implementations */
8603                         if(len<0)break;
8604
8605                         /* action */
8606                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8607                         COUNT_BYTES(4);
8608                         len -= 4;
8609                         /* broken implementations */
8610                         if(len<0)break;
8611
8612                         /* file name len */
8613                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8614                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8615                         COUNT_BYTES(4);
8616                         len -= 4;
8617                         /* broken implementations */
8618                         if(len<0)break;
8619
8620                         /* file name */
8621                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8622                         if (fn == NULL)
8623                                 break;
8624                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8625                                 fn);
8626                         COUNT_BYTES(fn_len);
8627                         len -= fn_len;
8628                         /* broken implementations */
8629                         if(len<0)break;
8630
8631                         if (neo == 0)
8632                                 break;  /* no more structures */
8633
8634                         /* skip to next structure */
8635                         padcnt = (old_offset + neo) - offset;
8636                         if (padcnt < 0) {
8637                                 /*
8638                                  * XXX - this is bogus; flag it?
8639                                  */
8640                                 padcnt = 0;
8641                         }
8642                         if (padcnt != 0) {
8643                                 COUNT_BYTES(padcnt);
8644                                 len -= padcnt;
8645                                 /* broken implementations */
8646                                 if(len<0)break;
8647                         }
8648                 }
8649                 break;
8650         case NT_TRANS_RENAME:
8651                 /* XXX not documented */
8652                 break;
8653         case NT_TRANS_QSD:
8654                 /*
8655                  * This appears to be the size of the security
8656                  * descriptor; the calling sequence of
8657                  * "ZwQuerySecurityObject()" suggests that it would
8658                  * be.  The actual security descriptor wouldn't
8659                  * follow if the max data count in the request
8660                  * was smaller; this lets the client know how
8661                  * big a buffer it needs to provide.
8662                  */
8663                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8664                 offset += 4;
8665                 break;
8666         case NT_TRANS_GET_USER_QUOTA:
8667                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8668                         tvb_get_letohl(tvb, offset));
8669                 offset += 4;
8670                 break;
8671         case NT_TRANS_SET_USER_QUOTA:
8672                 /* not decoded yet */
8673                 break;
8674         }
8675
8676         return offset;
8677 }
8678
8679 static int
8680 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8681                                 int offset, proto_tree *parent_tree,
8682                                 int len, nt_trans_data *ntd _U_)
8683 {
8684         proto_item *item = NULL;
8685         proto_tree *tree = NULL;
8686         smb_info_t *si;
8687         smb_nt_transact_info_t *nti;
8688
8689         si = (smb_info_t *)pinfo->private_data;
8690         DISSECTOR_ASSERT(si);
8691
8692         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8693                 nti = si->sip->extra_info;
8694         else
8695                 nti = NULL;
8696
8697         if(parent_tree){
8698                 tvb_ensure_bytes_exist(tvb, offset, len);
8699                 if(nti != NULL){
8700                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8701                                 "%s Setup",
8702                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8703                 } else {
8704                         /*
8705                          * We never saw the request to which this is a
8706                          * response.
8707                          */
8708                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8709                                 "Unknown NT Transaction Setup (matching request not seen)");
8710                 }
8711                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8712         }
8713
8714         if (nti == NULL) {
8715                 offset += len;
8716                 return offset;
8717         }
8718         switch(nti->subcmd){
8719         case NT_TRANS_CREATE:
8720                 break;
8721         case NT_TRANS_IOCTL:
8722                 break;
8723         case NT_TRANS_SSD:
8724                 break;
8725         case NT_TRANS_NOTIFY:
8726                 break;
8727         case NT_TRANS_RENAME:
8728                 /* XXX not documented */
8729                 break;
8730         case NT_TRANS_QSD:
8731                 break;
8732         case NT_TRANS_GET_USER_QUOTA:
8733                 /* not decoded yet */
8734                 break;
8735         case NT_TRANS_SET_USER_QUOTA:
8736                 /* not decoded yet */
8737                 break;
8738         }
8739
8740         return offset;
8741 }
8742
8743 static int
8744 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8745 {
8746         guint8 wc, sc;
8747         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8748         guint32 td=0, tp=0;
8749         smb_info_t *si;
8750         smb_nt_transact_info_t *nti=NULL;
8751         static nt_trans_data ntd;
8752         guint16 bc;
8753         gint32 padcnt;
8754         fragment_data *r_fd = NULL;
8755         tvbuff_t *pd_tvb=NULL;
8756         gboolean save_fragmented;
8757
8758         si = (smb_info_t *)pinfo->private_data;
8759         DISSECTOR_ASSERT(si);
8760
8761         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8762                 nti = si->sip->extra_info;
8763         else
8764                 nti = NULL;
8765
8766         /* primary request */
8767         if(nti != NULL){
8768                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8769                 if(check_col(pinfo->cinfo, COL_INFO)){
8770                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8771                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8772                 }
8773         } else {
8774                 proto_tree_add_text(tree, tvb, offset, 0,
8775                         "Function: <unknown function - could not find matching request>");
8776                 if(check_col(pinfo->cinfo, COL_INFO)){
8777                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8778                 }
8779         }
8780
8781         WORD_COUNT;
8782
8783         /* 3 reserved bytes */
8784         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8785         offset += 3;
8786
8787         /* total param count */
8788         tp = tvb_get_letohl(tvb, offset);
8789         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8790         offset += 4;
8791
8792         /* total data count */
8793         td = tvb_get_letohl(tvb, offset);
8794         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8795         offset += 4;
8796
8797         /* param count */
8798         pc = tvb_get_letohl(tvb, offset);
8799         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8800         offset += 4;
8801
8802         /* param offset */
8803         po = tvb_get_letohl(tvb, offset);
8804         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8805         offset += 4;
8806
8807         /* param displacement */
8808         pd = tvb_get_letohl(tvb, offset);
8809         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8810         offset += 4;
8811
8812         /* data count */
8813         dc = tvb_get_letohl(tvb, offset);
8814         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8815         offset += 4;
8816
8817         /* data offset */
8818         od = tvb_get_letohl(tvb, offset);
8819         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8820         offset += 4;
8821
8822         /* data displacement */
8823         dd = tvb_get_letohl(tvb, offset);
8824         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8825         offset += 4;
8826
8827         /* setup count */
8828         sc = tvb_get_guint8(tvb, offset);
8829         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8830         offset += 1;
8831
8832         /* setup data */
8833         if(sc){
8834                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8835                 offset += sc*2;
8836         }
8837
8838         BYTE_COUNT;
8839
8840         /* reassembly of SMB NT Transaction data payload.
8841            In this section we do reassembly of both the data and parameters
8842            blocks of the SMB transaction command.
8843         */
8844         save_fragmented = pinfo->fragmented;
8845         /* do we need reassembly? */
8846         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8847                 /* oh yeah, either data or parameter section needs
8848                    reassembly...
8849                 */
8850                 pinfo->fragmented = TRUE;
8851                 if(smb_trans_reassembly){
8852                         /* ...and we were told to do reassembly */
8853                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8854                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8855                                                              po, pc, pd, td+tp);
8856
8857                         }
8858                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8859                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8860                                                              od, dc, dd+tp, td+tp);
8861                         }
8862                 }
8863         }
8864
8865         /* if we got a reassembled fd structure from the reassembly routine we
8866            must create pd_tvb from it
8867         */
8868         if(r_fd){
8869         proto_item *frag_tree_item;
8870
8871                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8872                                              r_fd->datalen);
8873                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8874                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8875
8876                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
8877         }
8878
8879
8880         if(pd_tvb){
8881           /* we have reassembled data, grab param and data from there */
8882           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8883                                           &ntd, (guint16) tvb_length(pd_tvb));
8884           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
8885         } else {
8886           /* we do not have reassembled data, just use what we have in the
8887              packet as well as we can */
8888           /* parameters */
8889           if(po>(guint32)offset){
8890             /* We have some initial padding bytes.
8891              */
8892             padcnt = po-offset;
8893             if (padcnt > bc)
8894               padcnt = bc;
8895             CHECK_BYTE_COUNT(padcnt);
8896             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8897             COUNT_BYTES(padcnt);
8898           }
8899           if(pc){
8900             CHECK_BYTE_COUNT(pc);
8901             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8902             COUNT_BYTES(pc);
8903           }
8904
8905           /* data */
8906           if(od>(guint32)offset){
8907             /* We have some initial padding bytes.
8908              */
8909             padcnt = od-offset;
8910             if (padcnt > bc)
8911               padcnt = bc;
8912             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8913             COUNT_BYTES(padcnt);
8914           }
8915           if(dc){
8916             CHECK_BYTE_COUNT(dc);
8917             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti);
8918             COUNT_BYTES(dc);
8919           }
8920         }
8921         pinfo->fragmented = save_fragmented;
8922
8923         END_OF_SMB
8924
8925         return offset;
8926 }
8927
8928 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8929    NT Transaction command  ends here
8930    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8931
8932 static const value_string print_mode_vals[] = {
8933         {0,     "Text Mode"},
8934         {1,     "Graphics Mode"},
8935         {0, NULL}
8936 };
8937
8938 static int
8939 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8940 {
8941         smb_info_t *si = pinfo->private_data;
8942         int fn_len;
8943         const char *fn;
8944         guint8 wc;
8945         guint16 bc;
8946
8947         DISSECTOR_ASSERT(si);
8948
8949         WORD_COUNT;
8950
8951         /* setup len */
8952         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8953         offset += 2;
8954
8955         /* print mode */
8956         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8957         offset += 2;
8958
8959         BYTE_COUNT;
8960
8961         /* buffer format */
8962         CHECK_BYTE_COUNT(1);
8963         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8964         COUNT_BYTES(1);
8965
8966         /* print identifier */
8967         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8968         if (fn == NULL)
8969                 goto endofcommand;
8970         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8971                 fn);
8972         COUNT_BYTES(fn_len);
8973
8974         END_OF_SMB
8975
8976         return offset;
8977 }
8978
8979
8980 static int
8981 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8982 {
8983         int cnt;
8984         guint8 wc;
8985         guint16 bc, fid;
8986
8987         WORD_COUNT;
8988
8989         /* fid */
8990         fid = tvb_get_letohs(tvb, offset);
8991         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8992         offset += 2;
8993
8994         BYTE_COUNT;
8995
8996         /* buffer format */
8997         CHECK_BYTE_COUNT(1);
8998         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8999         COUNT_BYTES(1);
9000
9001         /* data len */
9002         CHECK_BYTE_COUNT(2);
9003         cnt = tvb_get_letohs(tvb, offset);
9004         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9005         COUNT_BYTES(2);
9006
9007         /* file data */
9008         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9009
9010         END_OF_SMB
9011
9012         return offset;
9013 }
9014
9015
9016 static const value_string print_status_vals[] = {
9017         {1,     "Held or Stopped"},
9018         {2,     "Printing"},
9019         {3,     "Awaiting print"},
9020         {4,     "In intercept"},
9021         {5,     "File had error"},
9022         {6,     "Printer error"},
9023         {0, NULL}
9024 };
9025
9026 static int
9027 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9028 {
9029         guint8 wc;
9030         guint16 bc;
9031
9032         WORD_COUNT;
9033
9034         /* max count */
9035         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9036         offset += 2;
9037
9038         /* start index */
9039         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9040         offset += 2;
9041
9042         BYTE_COUNT;
9043
9044         END_OF_SMB
9045
9046         return offset;
9047 }
9048
9049 static int
9050 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9051     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9052 {
9053         proto_item *item = NULL;
9054         proto_tree *tree = NULL;
9055         smb_info_t *si = pinfo->private_data;
9056         int fn_len;
9057         const char *fn;
9058
9059         DISSECTOR_ASSERT(si);
9060
9061         if(parent_tree){
9062                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9063                         "Queue entry");
9064                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9065         }
9066
9067         /* queued time */
9068         CHECK_BYTE_COUNT_SUBR(4);
9069         offset = dissect_smb_datetime(tvb, tree, offset,
9070                 hf_smb_print_queue_date,
9071                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9072         *bcp -= 4;
9073
9074         /* status */
9075         CHECK_BYTE_COUNT_SUBR(1);
9076         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9077         COUNT_BYTES_SUBR(1);
9078
9079         /* spool file number */
9080         CHECK_BYTE_COUNT_SUBR(2);
9081         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9082         COUNT_BYTES_SUBR(2);
9083
9084         /* spool file size */
9085         CHECK_BYTE_COUNT_SUBR(4);
9086         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9087         COUNT_BYTES_SUBR(4);
9088
9089         /* reserved byte */
9090         CHECK_BYTE_COUNT_SUBR(1);
9091         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9092         COUNT_BYTES_SUBR(1);
9093
9094         /* file name */
9095         fn_len = 16;
9096         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9097         CHECK_STRING_SUBR(fn);
9098         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9099                 fn);
9100         COUNT_BYTES_SUBR(fn_len);
9101
9102         *trunc = FALSE;
9103         return offset;
9104 }
9105
9106 static int
9107 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9108 {
9109         guint16 cnt=0, len;
9110         guint8 wc;
9111         guint16 bc;
9112         gboolean trunc;
9113
9114         WORD_COUNT;
9115
9116         /* count */
9117         cnt = tvb_get_letohs(tvb, offset);
9118         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9119         offset += 2;
9120
9121         /* restart index */
9122         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9123         offset += 2;
9124
9125         BYTE_COUNT;
9126
9127         /* buffer format */
9128         CHECK_BYTE_COUNT(1);
9129         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9130         COUNT_BYTES(1);
9131
9132         /* data len */
9133         CHECK_BYTE_COUNT(2);
9134         len = tvb_get_letohs(tvb, offset);
9135         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9136         COUNT_BYTES(2);
9137
9138         /* queue elements */
9139         while(cnt--){
9140                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9141                     &bc, &trunc);
9142                 if (trunc)
9143                         goto endofcommand;
9144         }
9145
9146         END_OF_SMB
9147
9148         return offset;
9149 }
9150
9151
9152 static int
9153 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9154 {
9155         int name_len;
9156         guint16 bc;
9157         guint8 wc;
9158         guint16 message_len;
9159
9160         WORD_COUNT;
9161
9162         BYTE_COUNT;
9163
9164         /* buffer format */
9165         CHECK_BYTE_COUNT(1);
9166         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9167         COUNT_BYTES(1);
9168
9169         /* originator name */
9170         /* XXX - what if this runs past bc? */
9171         name_len = tvb_strsize(tvb, offset);
9172         CHECK_BYTE_COUNT(name_len);
9173         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9174             name_len, TRUE);
9175         COUNT_BYTES(name_len);
9176
9177         /* buffer format */
9178         CHECK_BYTE_COUNT(1);
9179         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9180         COUNT_BYTES(1);
9181
9182         /* destination name */
9183         /* XXX - what if this runs past bc? */
9184         name_len = tvb_strsize(tvb, offset);
9185         CHECK_BYTE_COUNT(name_len);
9186         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9187             name_len, TRUE);
9188         COUNT_BYTES(name_len);
9189
9190         /* buffer format */
9191         CHECK_BYTE_COUNT(1);
9192         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9193         COUNT_BYTES(1);
9194
9195         /* message len */
9196         CHECK_BYTE_COUNT(2);
9197         message_len = tvb_get_letohs(tvb, offset);
9198         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9199             message_len);
9200         COUNT_BYTES(2);
9201
9202         /* message */
9203         CHECK_BYTE_COUNT(message_len);
9204         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9205             TRUE);
9206         COUNT_BYTES(message_len);
9207
9208         END_OF_SMB
9209
9210         return offset;
9211 }
9212
9213 static int
9214 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9215 {
9216         int name_len;
9217         guint16 bc;
9218         guint8 wc;
9219
9220         WORD_COUNT;
9221
9222         BYTE_COUNT;
9223
9224         /* buffer format */
9225         CHECK_BYTE_COUNT(1);
9226         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9227         COUNT_BYTES(1);
9228
9229         /* originator name */
9230         /* XXX - what if this runs past bc? */
9231         name_len = tvb_strsize(tvb, offset);
9232         CHECK_BYTE_COUNT(name_len);
9233         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9234             name_len, TRUE);
9235         COUNT_BYTES(name_len);
9236
9237         /* buffer format */
9238         CHECK_BYTE_COUNT(1);
9239         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9240         COUNT_BYTES(1);
9241
9242         /* destination name */
9243         /* XXX - what if this runs past bc? */
9244         name_len = tvb_strsize(tvb, offset);
9245         CHECK_BYTE_COUNT(name_len);
9246         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9247             name_len, TRUE);
9248         COUNT_BYTES(name_len);
9249
9250         END_OF_SMB
9251
9252         return offset;
9253 }
9254
9255 static int
9256 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9257 {
9258         guint16 bc;
9259         guint8 wc;
9260
9261         WORD_COUNT;
9262
9263         /* message group ID */
9264         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9265         offset += 2;
9266
9267         BYTE_COUNT;
9268
9269         END_OF_SMB
9270
9271         return offset;
9272 }
9273
9274 static int
9275 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9276 {
9277         guint16 bc;
9278         guint8 wc;
9279         guint16 message_len;
9280
9281         WORD_COUNT;
9282
9283         BYTE_COUNT;
9284
9285         /* buffer format */
9286         CHECK_BYTE_COUNT(1);
9287         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9288         COUNT_BYTES(1);
9289
9290         /* message len */
9291         CHECK_BYTE_COUNT(2);
9292         message_len = tvb_get_letohs(tvb, offset);
9293         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9294             message_len);
9295         COUNT_BYTES(2);
9296
9297         /* message */
9298         CHECK_BYTE_COUNT(message_len);
9299         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9300             TRUE);
9301         COUNT_BYTES(message_len);
9302
9303         END_OF_SMB
9304
9305         return offset;
9306 }
9307
9308 static int
9309 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9310 {
9311         int name_len;
9312         guint16 bc;
9313         guint8 wc;
9314
9315         WORD_COUNT;
9316
9317         BYTE_COUNT;
9318
9319         /* buffer format */
9320         CHECK_BYTE_COUNT(1);
9321         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9322         COUNT_BYTES(1);
9323
9324         /* forwarded name */
9325         /* XXX - what if this runs past bc? */
9326         name_len = tvb_strsize(tvb, offset);
9327         CHECK_BYTE_COUNT(name_len);
9328         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9329             name_len, TRUE);
9330         COUNT_BYTES(name_len);
9331
9332         END_OF_SMB
9333
9334         return offset;
9335 }
9336
9337 static int
9338 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9339 {
9340         int name_len;
9341         guint16 bc;
9342         guint8 wc;
9343
9344         WORD_COUNT;
9345
9346         BYTE_COUNT;
9347
9348         /* buffer format */
9349         CHECK_BYTE_COUNT(1);
9350         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9351         COUNT_BYTES(1);
9352
9353         /* machine name */
9354         /* XXX - what if this runs past bc? */
9355         name_len = tvb_strsize(tvb, offset);
9356         CHECK_BYTE_COUNT(name_len);
9357         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9358             name_len, TRUE);
9359         COUNT_BYTES(name_len);
9360
9361         END_OF_SMB
9362
9363         return offset;
9364 }
9365
9366
9367 static int
9368 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9369 {
9370         guint8  wc, cmd=0xff;
9371         guint16 andxoffset=0;
9372         guint16 bc;
9373         smb_info_t *si = pinfo->private_data;
9374         int fn_len;
9375         const char *fn;
9376         guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0;
9377
9378         DISSECTOR_ASSERT(si);
9379
9380         WORD_COUNT;
9381
9382         /* next smb command */
9383         cmd = tvb_get_guint8(tvb, offset);
9384         if(cmd!=0xff){
9385                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9386         } else {
9387                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9388         }
9389         offset += 1;
9390
9391         /* reserved byte */
9392         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9393         offset += 1;
9394
9395         /* andxoffset */
9396         andxoffset = tvb_get_letohs(tvb, offset);
9397         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9398         offset += 2;
9399
9400         /* reserved byte */
9401         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9402         offset += 1;
9403
9404         /* file name len */
9405         fn_len = tvb_get_letohs(tvb, offset);
9406         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9407         offset += 2;
9408
9409         /* Create flags */
9410         create_flags=tvb_get_letohl(tvb, offset);
9411         offset = dissect_nt_create_bits(tvb, tree, offset, create_flags);
9412
9413         /* root directory fid */
9414         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9415         offset += 4;
9416
9417         /* nt access mask */
9418         access_mask=tvb_get_letohl(tvb, offset);
9419         offset = dissect_smb_access_mask_bits(tvb, tree, offset, access_mask);
9420
9421         /* allocation size */
9422         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9423         offset += 8;
9424
9425         /* Extended File Attributes */
9426         file_attributes=tvb_get_letohl(tvb, offset);
9427         offset = dissect_file_ext_attr_bits(tvb, tree, offset, file_attributes);
9428
9429         /* share access */
9430         share_access=tvb_get_letohl(tvb, offset);
9431         offset = dissect_nt_share_access_bits(tvb, tree, offset, share_access);
9432
9433         /* create disposition */
9434         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9435         offset += 4;
9436
9437         /* create options */
9438         create_options=tvb_get_letohl(tvb, offset);
9439         offset = dissect_nt_create_options_bits(tvb, tree, offset, create_options);
9440
9441         /* impersonation level */
9442         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9443         offset += 4;
9444
9445         /* security flags */
9446         offset = dissect_nt_security_flags(tvb, tree, offset);
9447
9448         BYTE_COUNT;
9449
9450         /* file name */
9451         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9452         if (fn == NULL)
9453                 goto endofcommand;
9454         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9455                 fn);
9456         COUNT_BYTES(fn_len);
9457
9458         /* store it for the fid->name/openframe/closeframe matching in
9459          * dissect_smb_fid()   called from the response.
9460          */
9461         if((!pinfo->fd->flags.visited) && si->sip && fn){
9462                 smb_fid_saved_info_t *fsi;
9463
9464                 fsi=se_alloc(sizeof(smb_fid_saved_info_t));
9465                 fsi->filename=se_strdup(fn);
9466                 fsi->create_flags=create_flags;
9467                 fsi->access_mask=access_mask;
9468                 fsi->file_attributes=file_attributes;
9469                 fsi->share_access=share_access;
9470                 fsi->create_options=create_options;
9471
9472                 si->sip->extra_info_type=SMB_EI_FILEDATA;
9473                 si->sip->extra_info=fsi;
9474         }
9475
9476         if (check_col(pinfo->cinfo, COL_INFO)) {
9477                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9478                     format_text(fn, strlen(fn)));
9479         }
9480
9481         END_OF_SMB
9482
9483         if (cmd != 0xff) {      /* there is an andX command */
9484                 if (andxoffset < offset)
9485                         THROW(ReportedBoundsError);
9486                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9487         }
9488
9489         return offset;
9490 }
9491
9492
9493 static int
9494 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9495 {
9496         guint8  wc, cmd=0xff;
9497         guint16 andxoffset=0;
9498         guint16 bc;
9499         guint16 fid=0;
9500         guint16 ftype;
9501         guint8  isdir;
9502         smb_fid_info_t *fid_info=NULL;
9503         smb_info_t              *si;
9504
9505         si = pinfo->private_data;
9506
9507         WORD_COUNT;
9508
9509         /* next smb command */
9510         cmd = tvb_get_guint8(tvb, offset);
9511         if(cmd!=0xff){
9512                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9513         } else {
9514                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9515         }
9516         offset += 1;
9517
9518         /* reserved byte */
9519         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9520         offset += 1;
9521
9522         /* andxoffset */
9523         andxoffset = tvb_get_letohs(tvb, offset);
9524         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9525         offset += 2;
9526
9527         /* oplock level */
9528         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9529         offset += 1;
9530
9531         /* fid */
9532         fid = tvb_get_letohs(tvb, offset);
9533         fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
9534         offset += 2;
9535
9536         /* create action */
9537         /*XXX is this really the same as create disposition in the request? it looks so*/
9538         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9539         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9540         offset += 4;
9541
9542         /* create time */
9543         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
9544
9545         /* access time */
9546         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
9547
9548         /* last write time */
9549         offset = dissect_nt_64bit_time(tvb, tree, offset,
9550                 hf_smb_last_write_time);
9551
9552         /* last change time */
9553         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
9554
9555         /* Extended File Attributes */
9556         offset = dissect_file_ext_attr(tvb, tree, offset);
9557
9558         /* allocation size */
9559         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9560         offset += 8;
9561
9562         /* end of file */
9563         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9564         offset += 8;
9565
9566         /* File Type */
9567         ftype=tvb_get_letohs(tvb, offset);
9568         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9569         offset += 2;
9570
9571         /* IPC State */
9572         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9573
9574         /* is directory */
9575         isdir=tvb_get_guint8(tvb, offset);
9576         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9577         offset += 1;
9578
9579         /* Try to remember the type of this fid so that we can dissect
9580          * any future security descriptor (access mask) properly
9581          */
9582         if(ftype==0){
9583                 if(isdir==0){
9584                         if(fid_info){
9585                                 fid_info->type=SMB_FID_TYPE_FILE;
9586                         }
9587                 } else {
9588                         if(fid_info){
9589                                 fid_info->type=SMB_FID_TYPE_DIR;
9590                         }
9591                 }
9592         }
9593         if(ftype==2){
9594                 if(fid_info){
9595                         fid_info->type=SMB_FID_TYPE_PIPE;
9596                 }
9597         }               
9598
9599         BYTE_COUNT;
9600
9601         END_OF_SMB
9602
9603         if (cmd != 0xff) {      /* there is an andX command */
9604                 if (andxoffset < offset)
9605                         THROW(ReportedBoundsError);
9606                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9607         }
9608
9609         /* if there was an error, add a generated filename to the tree */
9610         if(si->nt_status){
9611                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
9612         }
9613
9614         return offset;
9615 }
9616
9617
9618 static int
9619 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9620 {
9621         guint8 wc;
9622         guint16 bc;
9623
9624         WORD_COUNT;
9625
9626         BYTE_COUNT;
9627
9628         END_OF_SMB
9629
9630         return offset;
9631 }
9632
9633 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9634    BEGIN Transaction/Transaction2 Primary and secondary requests
9635    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9636
9637
9638 const value_string trans2_cmd_vals[] = {
9639         { 0x00,         "OPEN2" },
9640         { 0x01,         "FIND_FIRST2" },
9641         { 0x02,         "FIND_NEXT2" },
9642         { 0x03,         "QUERY_FS_INFO" },
9643         { 0x04,         "SET_FS_QUOTA" },
9644         { 0x05,         "QUERY_PATH_INFO" },
9645         { 0x06,         "SET_PATH_INFO" },
9646         { 0x07,         "QUERY_FILE_INFO" },
9647         { 0x08,         "SET_FILE_INFO" },
9648         { 0x09,         "FSCTL" },
9649         { 0x0A,         "IOCTL2" },
9650         { 0x0B,         "FIND_NOTIFY_FIRST" },
9651         { 0x0C,         "FIND_NOTIFY_NEXT" },
9652         { 0x0D,         "CREATE_DIRECTORY" },
9653         { 0x0E,         "SESSION_SETUP" },
9654         { 0x10,         "GET_DFS_REFERRAL" },
9655         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9656         { 0,    NULL }
9657 };
9658
9659 static const true_false_string tfs_tf_dtid = {
9660         "Also DISCONNECT TID",
9661         "Do NOT disconnect TID"
9662 };
9663 static const true_false_string tfs_tf_owt = {
9664         "One Way Transaction (NO RESPONSE)",
9665         "Two way transaction"
9666 };
9667
9668 static const true_false_string tfs_ff2_backup = {
9669         "Find WITH backup intent",
9670         "No backup intent"
9671 };
9672 static const true_false_string tfs_ff2_continue = {
9673         "CONTINUE search from previous position",
9674         "New search, do NOT continue from previous position"
9675 };
9676 static const true_false_string tfs_ff2_resume = {
9677         "Return RESUME keys",
9678         "Do NOT return resume keys"
9679 };
9680 static const true_false_string tfs_ff2_close_eos = {
9681         "CLOSE search if END OF SEARCH is reached",
9682         "Do NOT close search if end of search reached"
9683 };
9684 static const true_false_string tfs_ff2_close = {
9685         "CLOSE search after this request",
9686         "Do NOT close search after this request"
9687 };
9688
9689 /* used by
9690    TRANS2_FIND_FIRST2
9691 */
9692 static const value_string ff2_il_vals[] = {
9693         { 1,            "Info Standard"},
9694         { 2,            "Info Query EA Size"},
9695         { 3,            "Info Query EAs From List"},
9696         { 0x0101,       "Find File Directory Info"},
9697         { 0x0102,       "Find File Full Directory Info"},
9698         { 0x0103,       "Find File Names Info"},
9699         { 0x0104,       "Find File Both Directory Info"},
9700         { 0x0202,       "Find File UNIX"},
9701         {0, NULL}
9702 };
9703
9704 /* values used by :
9705         TRANS2_QUERY_PATH_INFORMATION
9706         TRANS2_QUERY_FILE_INFORMATION
9707 */
9708 static const value_string qpi_loi_vals[] = {
9709         { 1,            "Info Standard"},
9710         { 2,            "Info Query EA Size"},
9711         { 3,            "Info Query EAs From List"},
9712         { 4,            "Info Query All EAs"},
9713         { 6,            "Info Is Name Valid"},
9714         { 0x0101,       "Query File Basic Info"},
9715         { 0x0102,       "Query File Standard Info"},
9716         { 0x0103,       "Query File EA Info"},
9717         { 0x0104,       "Query File Name Info"},
9718         { 0x0107,       "Query File All Info"},
9719         { 0x0108,       "Query File Alt Name Info"},
9720         { 0x0109,       "Query File Stream Info"},
9721         { 0x010b,       "Query File Compression Info"},
9722         { 0x0200,       "Query File Unix Basic"},
9723         { 0x0201,       "Query File Unix Link"},
9724         { 1004,         "Query File Basic Info"},
9725         { 1005,         "Query File Standard Info"},
9726         { 1006,         "Query File Internal Info"},
9727         { 1007,         "Query File EA Info"},
9728         { 1009,         "Query File Name Info"},
9729         { 1010,         "Query File Rename Info"},
9730         { 1011,         "Query File Link Info"},
9731         { 1012,         "Query File Names Info"},
9732         { 1013,         "Query File Disposition Info"},
9733         { 1014,         "Query File Position Info"},
9734         { 1015,         "Query File Full EA Info"},
9735         { 1016,         "Query File Mode Info"},
9736         { 1017,         "Query File Alignment Info"},
9737         { 1018,         "Query File All Info"},
9738         { 1019,         "Query File Allocation Info"},
9739         { 1020,         "Query File End of File Info"},
9740         { 1021,         "Query File Alt Name Info"},
9741         { 1022,         "Query File Stream Info"},
9742         { 1023,         "Query File Pipe Info"},
9743         { 1024,         "Query File Pipe Local Info"},
9744         { 1025,         "Query File Pipe Remote Info"},
9745         { 1026,         "Query File Mailslot Query Info"},
9746         { 1027,         "Query File Mailslot Set Info"},
9747         { 1028,         "Query File Compression Info"},
9748         { 1029,         "Query File ObjectID Info"},
9749         { 1030,         "Query File Completion Info"},
9750         { 1031,         "Query File Move Cluster Info"},
9751         { 1032,         "Query File Quota Info"},
9752         { 1033,         "Query File Reparsepoint Info"},
9753         { 1034,         "Query File Network Open Info"},
9754         { 1035,         "Query File Attribute Tag Info"},
9755         { 1036,         "Query File Tracking Info"},
9756         { 1037,         "Query File Maximum Info"},
9757         {0, NULL}
9758 };
9759
9760 /* values used by :
9761         TRANS2_SET_PATH_INFORMATION
9762         TRANS2_SET_FILE_INFORMATION
9763         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9764         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9765         well; note that they're different from the QUERY_PATH_INFORMATION
9766         and QUERY_FILE_INFORMATION values!)
9767 */
9768 static const value_string spi_loi_vals[] = {
9769         { 1,            "Info Standard"},
9770         { 2,            "Info Query EA Size"},
9771         { 4,            "Info Query All EAs"},
9772         { 0x0101,       "Set File Basic Info"},
9773         { 0x0102,       "Set File Disposition Info"},
9774         { 0x0103,       "Set File Allocation Info"},
9775         { 0x0104,       "Set File End Of File Info"},
9776         { 0x0200,       "Set File Unix Basic"},
9777         { 0x0201,       "Set File Unix Link"},
9778         { 0x0202,       "Set File Unix HardLink"},
9779         { 1004,         "Set File Basic Info"},
9780         { 1010,         "Set Rename Information"},
9781         { 1013,         "Set Disposition Information"},
9782         { 1014,         "Set Position Information"},
9783         { 1016,         "Set Mode Information"},
9784         { 1019,         "Set Allocation Information"},
9785         { 1020,         "Set EOF Information"},
9786         { 1023,         "Set File Pipe Information"},
9787         { 1025,         "Set File Pipe Remote Information"},
9788         { 1029,         "Set Copy On Write Information"},
9789         { 1032,         "Set OLE Class ID Information"},
9790         { 1039,         "Set Inherit Context Index Information"},
9791         { 1040,         "Set OLE Information (?)"},
9792         {0, NULL}
9793 };
9794
9795 static const value_string qfsi_vals[] = {
9796         { 1,            "Info Allocation"},
9797         { 2,            "Info Volume"},
9798         { 0x0101,       "Query FS Label Info"},
9799         { 0x0102,       "Query FS Volume Info"},
9800         { 0x0103,       "Query FS Size Info"},
9801         { 0x0104,       "Query FS Device Info"},
9802         { 0x0105,       "Query FS Attribute Info"},
9803         { 0x0200,       "Unix Query FS Info"},
9804         { 0x0301,       "Mac Query FS Info"},
9805         { 1001,         "Query FS Label Info"},
9806         { 1002,         "Query FS Volume Info"},
9807         { 1003,         "Query FS Size Info"},
9808         { 1004,         "Query FS Device Info"},
9809         { 1005,         "Query FS Attribute Info"},
9810         { 1006,         "Query FS Quota Info"},
9811         { 1007,         "Query Full FS Size Info"},
9812         { 1008,         "Object ID Information"},
9813         {0, NULL}
9814 };
9815
9816 static const value_string nt_rename_vals[] = {
9817         { 0x0103,       "Create Hard Link"},
9818         {0, NULL}
9819 };
9820
9821
9822 static const value_string delete_pending_vals[] = {
9823         {0,     "Normal, no pending delete"},
9824         {1,     "This object has DELETE PENDING"},
9825         {0, NULL}
9826 };
9827
9828 static const value_string alignment_vals[] = {
9829         {0,     "Byte alignment"},
9830         {1,     "Word (16bit) alignment"},
9831         {3,     "Long (32bit) alignment"},
9832         {7,     "8 byte boundary alignment"},
9833         {0x0f,  "16 byte boundary alignment"},
9834         {0x1f,  "32 byte boundary alignment"},
9835         {0x3f,  "64 byte boundary alignment"},
9836         {0x7f,  "128 byte boundary alignment"},
9837         {0xff,  "256 byte boundary alignment"},
9838         {0x1ff, "512 byte boundary alignment"},
9839         {0, NULL}
9840 };
9841
9842 static const true_false_string tfs_marked_for_deletion = {
9843         "File is MARKED FOR DELETION",
9844         "File is NOT marked for deletion"
9845 };
9846
9847 static const true_false_string tfs_get_dfs_server_hold_storage = {
9848         "Referral SERVER HOLDS STORAGE for the file",
9849         "Referral server does NOT hold storage for the file"
9850 };
9851 static const true_false_string tfs_get_dfs_fielding = {
9852         "The server in referral is FIELDING CAPABLE",
9853         "The server in referrals is NOT fielding capable"
9854 };
9855
9856 static const true_false_string tfs_dfs_referral_flags_strip = {
9857         "STRIP off pathconsumed characters before submitting",
9858         "Do NOT strip off any characters"
9859 };
9860
9861 static const value_string dfs_referral_server_type_vals[] = {
9862         {0,     "Don't know"},
9863         {1,     "SMB Server"},
9864         {2,     "Netware Server"},
9865         {3,     "Domain Server"},
9866         {0, NULL}
9867 };
9868
9869
9870 static const true_false_string tfs_device_char_removable = {
9871         "This is a REMOVABLE device",
9872         "This is NOT a removable device"
9873 };
9874 static const true_false_string tfs_device_char_read_only = {
9875         "This is a READ-ONLY device",
9876         "This is NOT a read-only device"
9877 };
9878 static const true_false_string tfs_device_char_floppy = {
9879         "This is a FLOPPY DISK device",
9880         "This is NOT a floppy disk device"
9881 };
9882 static const true_false_string tfs_device_char_write_once = {
9883         "This is a WRITE-ONCE device",
9884         "This is NOT a write-once device"
9885 };
9886 static const true_false_string tfs_device_char_remote = {
9887         "This is a REMOTE device",
9888         "This is NOT a remote device"
9889 };
9890 static const true_false_string tfs_device_char_mounted = {
9891         "This device is MOUNTED",
9892         "This device is NOT mounted"
9893 };
9894 static const true_false_string tfs_device_char_virtual = {
9895         "This is a VIRTUAL device",
9896         "This is NOT a virtual device"
9897 };
9898
9899
9900 static const true_false_string tfs_fs_attr_css = {
9901         "This FS supports CASE SENSITIVE SEARCHes",
9902         "This FS does NOT support case sensitive searches"
9903 };
9904 static const true_false_string tfs_fs_attr_cpn = {
9905         "This FS supports CASE PRESERVED NAMES",
9906         "This FS does NOT support case preserved names"
9907 };
9908 static const true_false_string tfs_fs_attr_uod = {
9909         "This FS supports UNICODE NAMES",
9910         "This FS does NOT support unicode names"
9911 };
9912 static const true_false_string tfs_fs_attr_pacls = {
9913         "This FS supports PERSISTENT ACLs",
9914         "This FS does NOT support persistent acls"
9915 };
9916 static const true_false_string tfs_fs_attr_fc = {
9917         "This FS supports COMPRESSED FILES",
9918         "This FS does NOT support compressed files"
9919 };
9920 static const true_false_string tfs_fs_attr_vq = {
9921         "This FS supports VOLUME QUOTAS",
9922         "This FS does NOT support volume quotas"
9923 };
9924 static const true_false_string tfs_fs_attr_srp = {
9925         "This FS supports REPARSE POINTS",
9926         "This FS does NOT support reparse points"
9927 };
9928 static const true_false_string tfs_fs_attr_srs = {
9929         "This FS supports REMOTE STORAGE",
9930         "This FS does NOT support remote storage"
9931 };
9932 static const true_false_string tfs_fs_attr_ssf = {
9933         "This FS supports SPARSE FILES",
9934         "This FS does NOT support sparse files"
9935 };
9936 static const true_false_string tfs_fs_attr_sla = {
9937         "This FS supports LFN APIs",
9938         "This FS does NOT support lfn apis"
9939 };
9940 static const true_false_string tfs_fs_attr_vic = {
9941         "This FS VOLUME IS COMPRESSED",
9942         "This FS volume is NOT compressed"
9943 };
9944 static const true_false_string tfs_fs_attr_soids = {
9945         "This FS supports OIDs",
9946         "This FS does NOT support OIDs"
9947 };
9948 static const true_false_string tfs_fs_attr_se = {
9949         "This FS supports ENCRYPTION",
9950         "This FS does NOT support encryption"
9951 };
9952 static const true_false_string tfs_fs_attr_ns = {
9953         "This FS supports NAMED STREAMS",
9954         "This FS does NOT support named streams"
9955 };
9956 static const true_false_string tfs_fs_attr_rov = {
9957         "This is a READ ONLY VOLUME",
9958         "This is a read/write volume"
9959 };
9960
9961 #define FF2_RESUME      0x0004
9962
9963 static int
9964 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9965 {
9966         guint16 mask;
9967         proto_item *item = NULL;
9968         proto_tree *tree = NULL;
9969         smb_info_t *si;
9970         smb_transact2_info_t *t2i;
9971
9972         mask = tvb_get_letohs(tvb, offset);
9973
9974         si = (smb_info_t *)pinfo->private_data;
9975         DISSECTOR_ASSERT(si);
9976
9977         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
9978                 t2i = si->sip->extra_info;
9979                 if (t2i != NULL) {
9980                         if (!pinfo->fd->flags.visited)
9981                                 t2i->resume_keys = (mask & FF2_RESUME);
9982                 }
9983         }
9984
9985         if(parent_tree){
9986                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9987                         "Flags: 0x%04x", mask);
9988                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9989         }
9990
9991         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9992                 tvb, offset, 2, mask);
9993         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9994                 tvb, offset, 2, mask);
9995         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9996                 tvb, offset, 2, mask);
9997         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9998                 tvb, offset, 2, mask);
9999         proto_tree_add_boolean(tree, hf_smb_ff2_close,
10000                 tvb, offset, 2, mask);
10001
10002         offset += 2;
10003
10004         return offset;
10005 }
10006
10007 #if 0
10008 static int
10009 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10010 {
10011         guint16 mask;
10012         proto_item *item = NULL;
10013         proto_tree *tree = NULL;
10014
10015         mask = tvb_get_letohs(tvb, offset);
10016
10017         if(parent_tree){
10018                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10019                         "IO Flag: 0x%04x", mask);
10020                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10021         }
10022
10023         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10024                 tvb, offset, 2, mask);
10025         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10026                 tvb, offset, 2, mask);
10027
10028         offset += 2;
10029
10030         return offset;
10031 }
10032 #endif
10033
10034 static int
10035 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10036     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10037 {
10038         proto_item *item = NULL;
10039         proto_tree *tree = NULL;
10040         smb_info_t *si;
10041         smb_transact2_info_t *t2i;
10042         int fn_len;
10043         const char *fn;
10044
10045         si = (smb_info_t *)pinfo->private_data;
10046         DISSECTOR_ASSERT(si);
10047
10048         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
10049                 t2i = si->sip->extra_info;
10050         else
10051                 t2i = NULL;
10052
10053         if(parent_tree){
10054                 tvb_ensure_bytes_exist(tvb, offset, bc);
10055                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10056                                 "%s Parameters",
10057                                 val_to_str(subcmd, trans2_cmd_vals,
10058                                            "Unknown (0x%02x)"));
10059                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10060         }
10061
10062         switch(subcmd){
10063         case 0x00:      /*TRANS2_OPEN2*/
10064                 /* open flags */
10065                 CHECK_BYTE_COUNT_TRANS(2);
10066                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10067                 bc -= 2;
10068
10069                 /* desired access */
10070                 CHECK_BYTE_COUNT_TRANS(2);
10071                 offset = dissect_access(tvb, tree, offset, "Desired");
10072                 bc -= 2;
10073
10074                 /* Search Attributes */
10075                 CHECK_BYTE_COUNT_TRANS(2);
10076                 offset = dissect_search_attributes(tvb, tree, offset);
10077                 bc -= 2;
10078
10079                 /* File Attributes */
10080                 CHECK_BYTE_COUNT_TRANS(2);
10081                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10082                 bc -= 2;
10083
10084                 /* create time */
10085                 CHECK_BYTE_COUNT_TRANS(4);
10086                 offset = dissect_smb_datetime(tvb, tree, offset,
10087                         hf_smb_create_time,
10088                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10089                         TRUE);
10090                 bc -= 4;
10091
10092                 /* open function */
10093                 CHECK_BYTE_COUNT_TRANS(2);
10094                 offset = dissect_open_function(tvb, tree, offset);
10095                 bc -= 2;
10096
10097                 /* allocation size */
10098                 CHECK_BYTE_COUNT_TRANS(4);
10099                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10100                 COUNT_BYTES_TRANS(4);
10101
10102                 /* 10 reserved bytes */
10103                 CHECK_BYTE_COUNT_TRANS(10);
10104                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10105                 COUNT_BYTES_TRANS(10);
10106
10107                 /* file name */
10108                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10109                 CHECK_STRING_TRANS(fn);
10110                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10111                         fn);
10112                 COUNT_BYTES_TRANS(fn_len);
10113
10114                 if (check_col(pinfo->cinfo, COL_INFO)) {
10115                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10116                             format_text(fn, strlen(fn)));
10117                 }
10118                 break;
10119         case 0x01:      /*TRANS2_FIND_FIRST2*/
10120                 /* Search Attributes */
10121                 CHECK_BYTE_COUNT_TRANS(2);
10122                 offset = dissect_search_attributes(tvb, tree, offset);
10123                 bc -= 2;
10124
10125                 /* search count */
10126                 CHECK_BYTE_COUNT_TRANS(2);
10127                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10128                 COUNT_BYTES_TRANS(2);
10129
10130                 /* Find First2 flags */
10131                 CHECK_BYTE_COUNT_TRANS(2);
10132                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10133                 bc -= 2;
10134
10135                 /* Find First2 information level */
10136                 CHECK_BYTE_COUNT_TRANS(2);
10137                 si->info_level = tvb_get_letohs(tvb, offset);
10138                 if (t2i != NULL && !pinfo->fd->flags.visited)
10139                         t2i->info_level = si->info_level;
10140                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10141                 COUNT_BYTES_TRANS(2);
10142
10143                 /* storage type */
10144                 CHECK_BYTE_COUNT_TRANS(4);
10145                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10146                 COUNT_BYTES_TRANS(4);
10147
10148                 /* search pattern */
10149                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10150                 CHECK_STRING_TRANS(fn);
10151                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10152                         fn);
10153                 COUNT_BYTES_TRANS(fn_len);
10154
10155                 if (check_col(pinfo->cinfo, COL_INFO)) {
10156                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10157                             format_text(fn, strlen(fn)));
10158                 }
10159
10160                 break;
10161         case 0x02:      /*TRANS2_FIND_NEXT2*/
10162                 /* sid */
10163                 CHECK_BYTE_COUNT_TRANS(2);
10164                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10165                 COUNT_BYTES_TRANS(2);
10166
10167                 /* search count */
10168                 CHECK_BYTE_COUNT_TRANS(2);
10169                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10170                 COUNT_BYTES_TRANS(2);
10171
10172                 /* Find First2 information level */
10173                 CHECK_BYTE_COUNT_TRANS(2);
10174                 si->info_level = tvb_get_letohs(tvb, offset);
10175                 if (t2i != NULL && !pinfo->fd->flags.visited)
10176                         t2i->info_level = si->info_level;
10177                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10178                 COUNT_BYTES_TRANS(2);
10179
10180                 /* resume key */
10181                 CHECK_BYTE_COUNT_TRANS(4);
10182                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10183                 COUNT_BYTES_TRANS(4);
10184
10185                 /* Find First2 flags */
10186                 CHECK_BYTE_COUNT_TRANS(2);
10187                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10188                 bc -= 2;
10189
10190                 /* file name */
10191                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10192                 CHECK_STRING_TRANS(fn);
10193                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10194                         fn);
10195                 COUNT_BYTES_TRANS(fn_len);
10196
10197                 if (check_col(pinfo->cinfo, COL_INFO)) {
10198                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10199                             format_text(fn, strlen(fn)));
10200                 }
10201
10202                 break;
10203         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10204                 /* level of interest */
10205                 CHECK_BYTE_COUNT_TRANS(2);
10206                 si->info_level = tvb_get_letohs(tvb, offset);
10207                 if (t2i != NULL && !pinfo->fd->flags.visited)
10208                         t2i->info_level = si->info_level;
10209                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10210                 COUNT_BYTES_TRANS(2);
10211
10212                 if (check_col(pinfo->cinfo, COL_INFO))
10213                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10214                                         val_to_str(si->info_level, qfsi_vals, 
10215                                                    "Unknown (0x%02x)"));
10216
10217                 break;
10218         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10219                 /* level of interest */
10220                 CHECK_BYTE_COUNT_TRANS(2);
10221                 si->info_level = tvb_get_letohs(tvb, offset);
10222                 if (t2i != NULL && !pinfo->fd->flags.visited)
10223                         t2i->info_level = si->info_level;
10224                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10225                 COUNT_BYTES_TRANS(2);
10226
10227                 if (check_col(pinfo->cinfo, COL_INFO)) {
10228                         col_append_fstr(
10229                                 pinfo->cinfo, COL_INFO, ", %s", 
10230                                 val_to_str(si->info_level, qpi_loi_vals, 
10231                                            "Unknown (%u)"));
10232                 }
10233
10234                 /* 4 reserved bytes */
10235                 CHECK_BYTE_COUNT_TRANS(4);
10236                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10237                 COUNT_BYTES_TRANS(4);
10238
10239                 /* file name */
10240                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10241                 CHECK_STRING_TRANS(fn);
10242                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10243                         fn);
10244                 COUNT_BYTES_TRANS(fn_len);
10245
10246                 if (check_col(pinfo->cinfo, COL_INFO)) {
10247                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10248                             format_text(fn, strlen(fn)));
10249                 }
10250
10251                 break;
10252         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10253                 /* level of interest */
10254                 CHECK_BYTE_COUNT_TRANS(2);
10255                 si->info_level = tvb_get_letohs(tvb, offset);
10256                 if (t2i != NULL && !pinfo->fd->flags.visited)
10257                         t2i->info_level = si->info_level;
10258                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10259                 COUNT_BYTES_TRANS(2);
10260
10261                 /* 4 reserved bytes */
10262                 CHECK_BYTE_COUNT_TRANS(4);
10263                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10264                 COUNT_BYTES_TRANS(4);
10265
10266                 /* file name */
10267                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10268                 CHECK_STRING_TRANS(fn);
10269                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10270                         fn);
10271                 COUNT_BYTES_TRANS(fn_len);
10272
10273                 if (check_col(pinfo->cinfo, COL_INFO)) {
10274                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10275                             format_text(fn, strlen(fn)));
10276                 }
10277
10278                 break;
10279         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10280                 guint16 fid;
10281
10282                 /* fid */
10283                 CHECK_BYTE_COUNT_TRANS(2);
10284                 fid = tvb_get_letohs(tvb, offset);
10285                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10286                 COUNT_BYTES_TRANS(2);
10287
10288                 /* level of interest */
10289                 CHECK_BYTE_COUNT_TRANS(2);
10290                 si->info_level = tvb_get_letohs(tvb, offset);
10291                 if (t2i != NULL && !pinfo->fd->flags.visited)
10292                         t2i->info_level = si->info_level;
10293                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10294                 COUNT_BYTES_TRANS(2);
10295
10296                 if (check_col(pinfo->cinfo, COL_INFO)) {
10297                         col_append_fstr(
10298                                 pinfo->cinfo, COL_INFO, ", %s", 
10299                                 val_to_str(si->info_level, qpi_loi_vals, 
10300                                            "Unknown (%u)"));
10301                 }
10302
10303                 break;
10304         }
10305         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10306                 guint16 fid;
10307
10308                 /* fid */
10309                 CHECK_BYTE_COUNT_TRANS(2);
10310                 fid = tvb_get_letohs(tvb, offset);
10311                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10312                 COUNT_BYTES_TRANS(2);
10313
10314                 /* level of interest */
10315                 CHECK_BYTE_COUNT_TRANS(2);
10316                 si->info_level = tvb_get_letohs(tvb, offset);
10317                 if (t2i != NULL && !pinfo->fd->flags.visited)
10318                         t2i->info_level = si->info_level;
10319                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10320                 COUNT_BYTES_TRANS(2);
10321
10322 #if 0
10323                 /*
10324                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10325                  * Extensions Version 3.0, Document Version 1.11,
10326                  * July 19, 1990" says this is I/O flags, but it's
10327                  * reserved in the SNIA spec, and some clients appear
10328                  * to leave junk in it.
10329                  *
10330                  * Is this some field used only if a particular
10331                  * dialect was negotiated, so that clients can feel
10332                  * safe not setting it if they haven't negotiated that
10333                  * dialect?  Or do the (non-OS/2) clients simply not care
10334                  * about that particular OS/2-oriented dialect?
10335                  */
10336
10337                 /* IO Flag */
10338                 CHECK_BYTE_COUNT_TRANS(2);
10339                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10340                 bc -= 2;
10341 #else
10342                 /* 2 reserved bytes */
10343                 CHECK_BYTE_COUNT_TRANS(2);
10344                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10345                 COUNT_BYTES_TRANS(2);
10346 #endif
10347
10348                 break;
10349         }
10350         case 0x09:      /*TRANS2_FSCTL*/
10351                 /* this call has no parameter block in the request */
10352
10353                 /*
10354                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10355                  * Extensions Version 3.0, Document Version 1.11,
10356                  * July 19, 1990" says this this contains a
10357                  * "File system specific parameter block".  (That means
10358                  * we may not be able to dissect it in any case.)
10359                  */
10360                 break;
10361         case 0x0a:      /*TRANS2_IOCTL2*/
10362                 /* this call has no parameter block in the request */
10363
10364                 /*
10365                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10366                  * Extensions Version 3.0, Document Version 1.11,
10367                  * July 19, 1990" says this this contains a
10368                  * "Device/function specific parameter block".  (That
10369                  * means we may not be able to dissect it in any case.)
10370                  */
10371                 break;
10372         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10373                 /* Search Attributes */
10374                 CHECK_BYTE_COUNT_TRANS(2);
10375                 offset = dissect_search_attributes(tvb, tree, offset);
10376                 bc -= 2;
10377
10378                 /* Number of changes to wait for */
10379                 CHECK_BYTE_COUNT_TRANS(2);
10380                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10381                 COUNT_BYTES_TRANS(2);
10382
10383                 /* Find Notify information level */
10384                 CHECK_BYTE_COUNT_TRANS(2);
10385                 si->info_level = tvb_get_letohs(tvb, offset);
10386                 if (t2i != NULL && !pinfo->fd->flags.visited)
10387                         t2i->info_level = si->info_level;
10388                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10389                 COUNT_BYTES_TRANS(2);
10390
10391                 /* 4 reserved bytes */
10392                 CHECK_BYTE_COUNT_TRANS(4);
10393                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10394                 COUNT_BYTES_TRANS(4);
10395
10396                 /* file name */
10397                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10398                 CHECK_STRING_TRANS(fn);
10399                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10400                         fn);
10401                 COUNT_BYTES_TRANS(fn_len);
10402
10403                 if (check_col(pinfo->cinfo, COL_INFO)) {
10404                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10405                             format_text(fn, strlen(fn)));
10406                 }
10407
10408                 break;
10409         }
10410         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10411                 /* Monitor handle */
10412                 CHECK_BYTE_COUNT_TRANS(2);
10413                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10414                 COUNT_BYTES_TRANS(2);
10415
10416                 /* Number of changes to wait for */
10417                 CHECK_BYTE_COUNT_TRANS(2);
10418                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10419                 COUNT_BYTES_TRANS(2);
10420
10421                 break;
10422         }
10423         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10424                 /* 4 reserved bytes */
10425                 CHECK_BYTE_COUNT_TRANS(4);
10426                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10427                 COUNT_BYTES_TRANS(4);
10428
10429                 /* dir name */
10430                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10431                         FALSE, FALSE, &bc);
10432                 CHECK_STRING_TRANS(fn);
10433                 proto_tree_add_string(tree, hf_smb_dir_name, 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, ", Dir: %s",
10439                             format_text(fn, strlen(fn)));
10440                 }
10441                 break;
10442         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10443                 /* XXX unknown structure*/
10444                 break;
10445         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10446                 /* referral level */
10447                 CHECK_BYTE_COUNT_TRANS(2);
10448                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10449                 COUNT_BYTES_TRANS(2);
10450
10451                 /* file name */
10452                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10453                 CHECK_STRING_TRANS(fn);
10454                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10455                         fn);
10456                 COUNT_BYTES_TRANS(fn_len);
10457
10458                 if (check_col(pinfo->cinfo, COL_INFO)) {
10459                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10460                             format_text(fn, strlen(fn)));
10461                 }
10462
10463                 break;
10464         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10465                 /* file name */
10466                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10467                 CHECK_STRING_TRANS(fn);
10468                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10469                         fn);
10470                 COUNT_BYTES_TRANS(fn_len);
10471
10472                 if (check_col(pinfo->cinfo, COL_INFO)) {
10473                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10474                             format_text(fn, strlen(fn)));
10475                 }
10476
10477                 break;
10478         }
10479
10480         /* ooops there were data we didnt know how to process */
10481         if(bc != 0){
10482                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10483                 offset += bc;
10484         }
10485
10486         return offset;
10487 }
10488
10489 /*
10490  * XXX - just use "dissect_connect_flags()" here?
10491  */
10492 static guint16
10493 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10494 {
10495         guint16 mask;
10496         proto_item *item = NULL;
10497         proto_tree *tree = NULL;
10498
10499         mask = tvb_get_letohs(tvb, offset);
10500
10501         if(parent_tree){
10502                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10503                         "Flags: 0x%04x", mask);
10504                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10505         }
10506
10507         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10508                 tvb, offset, 2, mask);
10509         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10510                 tvb, offset, 2, mask);
10511
10512         return mask;
10513 }
10514
10515
10516 static int
10517 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10518 {
10519         guint16 mask;
10520         proto_item *item = NULL;
10521         proto_tree *tree = NULL;
10522
10523         mask = tvb_get_letohs(tvb, offset);
10524
10525         if(parent_tree){
10526                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10527                         "Flags: 0x%04x", mask);
10528                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10529         }
10530
10531         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10532                 tvb, offset, 2, mask);
10533         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10534                 tvb, offset, 2, mask);
10535
10536         offset += 2;
10537         return offset;
10538 }
10539
10540 static int
10541 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10542 {
10543         guint16 mask;
10544         proto_item *item = NULL;
10545         proto_tree *tree = NULL;
10546
10547         mask = tvb_get_letohs(tvb, offset);
10548
10549         if(parent_tree){
10550                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10551                         "Flags: 0x%04x", mask);
10552                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10553         }
10554
10555         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10556                 tvb, offset, 2, mask);
10557
10558         offset += 2;
10559
10560         return offset;
10561 }
10562
10563
10564 /* dfs inconsistency data  (4.4.2)
10565 */
10566 static int
10567 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10568     proto_tree *tree, int offset, guint16 *bcp)
10569 {
10570         smb_info_t *si = pinfo->private_data;
10571         int fn_len;
10572         const char *fn;
10573
10574         DISSECTOR_ASSERT(si);
10575
10576         /*XXX shouldn this data hold version and size? unclear from doc*/
10577         /* referral version */
10578         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10579         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10580         COUNT_BYTES_TRANS_SUBR(2);
10581
10582         /* referral size */
10583         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10584         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10585         COUNT_BYTES_TRANS_SUBR(2);
10586
10587         /* referral server type */
10588         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10589         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10590         COUNT_BYTES_TRANS_SUBR(2);
10591
10592         /* referral flags */
10593         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10594         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10595         *bcp -= 2;
10596
10597         /* node name */
10598         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10599         CHECK_STRING_TRANS_SUBR(fn);
10600         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10601                 fn);
10602         COUNT_BYTES_TRANS_SUBR(fn_len);
10603
10604         return offset;
10605 }
10606
10607 /* get dfs referral data  (4.4.1)
10608 */
10609 static int
10610 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10611     proto_tree *tree, int offset, guint16 *bcp)
10612 {
10613         smb_info_t *si = pinfo->private_data;
10614         guint16 numref;
10615         guint16 refsize;
10616         guint16 pathoffset;
10617         guint16 altpathoffset;
10618         guint16 nodeoffset;
10619         int fn_len;
10620         int stroffset;
10621         int offsetoffset;
10622         guint16 save_bc;
10623         const char *fn;
10624         int unklen;
10625         int ucstring_end;
10626         int ucstring_len;
10627
10628         DISSECTOR_ASSERT(si);
10629
10630         /* path consumed */
10631         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10632         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10633         COUNT_BYTES_TRANS_SUBR(2);
10634
10635         /* num referrals */
10636         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10637         numref = tvb_get_letohs(tvb, offset);
10638         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10639         COUNT_BYTES_TRANS_SUBR(2);
10640
10641         /* get dfs flags */
10642         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10643         offset = dissect_get_dfs_flags(tvb, tree, offset);
10644         *bcp -= 2;
10645
10646         /* XXX - in at least one capture there appears to be 2 bytes
10647            of stuff after the Dfs flags, perhaps so that the header
10648            in front of the referral list is a multiple of 4 bytes long. */
10649         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10650         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10651         COUNT_BYTES_TRANS_SUBR(2);
10652
10653         /* if there are any referrals */
10654         if(numref){
10655                 proto_item *ref_item = NULL;
10656                 proto_tree *ref_tree = NULL;
10657                 int old_offset=offset;
10658
10659                 if(tree){
10660                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
10661                         ref_item = proto_tree_add_text(tree,
10662                                 tvb, offset, *bcp, "Referrals");
10663                         ref_tree = proto_item_add_subtree(ref_item,
10664                                 ett_smb_dfs_referrals);
10665                 }
10666                 ucstring_end = -1;
10667
10668                 while(numref--){
10669                         proto_item *ri = NULL;
10670                         proto_tree *rt = NULL;
10671                         int old_offset=offset;
10672                         guint16 version;
10673
10674                         if(tree){
10675                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
10676                                 ri = proto_tree_add_text(ref_tree,
10677                                         tvb, offset, *bcp, "Referral");
10678                                 rt = proto_item_add_subtree(ri,
10679                                         ett_smb_dfs_referral);
10680                         }
10681
10682                         /* referral version */
10683                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10684                         version = tvb_get_letohs(tvb, offset);
10685                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10686                                 tvb, offset, 2, version);
10687                         COUNT_BYTES_TRANS_SUBR(2);
10688
10689                         /* referral size */
10690                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10691                         refsize = tvb_get_letohs(tvb, offset);
10692                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10693                         COUNT_BYTES_TRANS_SUBR(2);
10694
10695                         /* referral server type */
10696                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10697                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10698                         COUNT_BYTES_TRANS_SUBR(2);
10699
10700                         /* referral flags */
10701                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10702                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10703                         *bcp -= 2;
10704
10705                         switch(version){
10706
10707                         case 1:
10708                                 /* node name */
10709                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10710                                 CHECK_STRING_TRANS_SUBR(fn);
10711                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10712                                         fn);
10713                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10714                                 break;
10715
10716                         case 2:
10717                         case 3: /* XXX - like version 2, but not identical;
10718                                    seen in a capture, but the format isn't
10719                                    documented */
10720                                 /* proximity */
10721                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10722                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10723                                 COUNT_BYTES_TRANS_SUBR(2);
10724
10725                                 /* ttl */
10726                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10727                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10728                                 COUNT_BYTES_TRANS_SUBR(2);
10729
10730                                 /* path offset */
10731                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10732                                 pathoffset = tvb_get_letohs(tvb, offset);
10733                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10734                                 COUNT_BYTES_TRANS_SUBR(2);
10735
10736                                 /* alt path offset */
10737                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10738                                 altpathoffset = tvb_get_letohs(tvb, offset);
10739                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10740                                 COUNT_BYTES_TRANS_SUBR(2);
10741
10742                                 /* node offset */
10743                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10744                                 nodeoffset = tvb_get_letohs(tvb, offset);
10745                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10746                                 COUNT_BYTES_TRANS_SUBR(2);
10747
10748                                 /* path */
10749                                 if (pathoffset != 0) {
10750                                         stroffset = old_offset + pathoffset;
10751                                         offsetoffset = stroffset - offset;
10752                                         if (offsetoffset > 0 &&
10753                                             *bcp > offsetoffset) {
10754                                                 save_bc = *bcp;
10755                                                 *bcp -= offsetoffset;
10756                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10757                                                 CHECK_STRING_TRANS_SUBR(fn);
10758                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10759                                                         fn);
10760                                                 stroffset += fn_len;
10761                                                 if (ucstring_end < stroffset)
10762                                                         ucstring_end = stroffset;
10763                                                 *bcp = save_bc;
10764                                         }
10765                                 }
10766
10767                                 /* alt path */
10768                                 if (altpathoffset != 0) {
10769                                         stroffset = old_offset + altpathoffset;
10770                                         offsetoffset = stroffset - offset;
10771                                         if (offsetoffset > 0 &&
10772                                             *bcp > offsetoffset) {
10773                                                 save_bc = *bcp;
10774                                                 *bcp -= offsetoffset;
10775                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10776                                                 CHECK_STRING_TRANS_SUBR(fn);
10777                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10778                                                         fn);
10779                                                 stroffset += fn_len;
10780                                                 if (ucstring_end < stroffset)
10781                                                         ucstring_end = stroffset;
10782                                                 *bcp = save_bc;
10783                                         }
10784                                 }
10785
10786                                 /* node */
10787                                 if (nodeoffset != 0) {
10788                                         stroffset = old_offset + nodeoffset;
10789                                         offsetoffset = stroffset - offset;
10790                                         if (offsetoffset > 0 &&
10791                                             *bcp > offsetoffset) {
10792                                                 save_bc = *bcp;
10793                                                 *bcp -= offsetoffset;
10794                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10795                                                 CHECK_STRING_TRANS_SUBR(fn);
10796                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10797                                                         fn);
10798                                                 stroffset += fn_len;
10799                                                 if (ucstring_end < stroffset)
10800                                                         ucstring_end = stroffset;
10801                                                 *bcp = save_bc;
10802                                         }
10803                                 }
10804                                 break;
10805                         }
10806
10807                         /*
10808                          * Show anything beyond the length of the referral
10809                          * as unknown data.
10810                          */
10811                         unklen = (old_offset + refsize) - offset;
10812                         if (unklen < 0) {
10813                                 /*
10814                                  * XXX - the length is bogus.
10815                                  */
10816                                 unklen = 0;
10817                         }
10818                         if (unklen != 0) {
10819                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10820                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10821                                     offset, unklen, TRUE);
10822                                 COUNT_BYTES_TRANS_SUBR(unklen);
10823                         }
10824
10825                         proto_item_set_len(ri, offset-old_offset);
10826                 }
10827
10828                 /*
10829                  * Treat the offset past the end of the last Unicode
10830                  * string after the referrals (if any) as the last
10831                  * offset.
10832                  */
10833                 if (ucstring_end > offset) {
10834                         ucstring_len = ucstring_end - offset;
10835                         if (*bcp < ucstring_len)
10836                                 ucstring_len = *bcp;
10837                         offset += ucstring_len;
10838                         *bcp -= ucstring_len;
10839                 }
10840                 proto_item_set_len(ref_item, offset-old_offset);
10841         }
10842
10843         return offset;
10844 }
10845
10846 /* This dissects the standard four 8-byte Windows timestamps ...
10847  */
10848 static int
10849 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
10850     packet_info *pinfo _U_, proto_tree *tree,
10851     int offset, guint16 *bcp, gboolean *trunc)
10852 {
10853         /* create time */
10854         CHECK_BYTE_COUNT_SUBR(8);
10855         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
10856         *bcp -= 8;
10857
10858         /* access time */
10859         CHECK_BYTE_COUNT_SUBR(8);
10860         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
10861         *bcp -= 8;
10862
10863         /* last write time */
10864         CHECK_BYTE_COUNT_SUBR(8);
10865         offset = dissect_nt_64bit_time(tvb, tree, offset,
10866                 hf_smb_last_write_time);
10867         *bcp -= 8;
10868
10869         /* last change time */
10870         CHECK_BYTE_COUNT_SUBR(8);
10871         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
10872         *bcp -= 8;
10873
10874         *trunc = FALSE;
10875         return offset;
10876 }
10877
10878 /* this dissects the SMB_INFO_STANDARD
10879    as described in 4.2.16.1
10880 */
10881 static int
10882 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10883     int offset, guint16 *bcp, gboolean *trunc)
10884 {
10885         /* create time */
10886         CHECK_BYTE_COUNT_SUBR(4);
10887         offset = dissect_smb_datetime(tvb, tree, offset,
10888                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10889                 FALSE);
10890         *bcp -= 4;
10891
10892         /* access time */
10893         CHECK_BYTE_COUNT_SUBR(4);
10894         offset = dissect_smb_datetime(tvb, tree, offset,
10895                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10896                 FALSE);
10897         *bcp -= 4;
10898
10899         /* last write time */
10900         CHECK_BYTE_COUNT_SUBR(4);
10901         offset = dissect_smb_datetime(tvb, tree, offset,
10902                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10903                 FALSE);
10904         *bcp -= 4;
10905
10906         /* data size */
10907         CHECK_BYTE_COUNT_SUBR(4);
10908         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10909         COUNT_BYTES_SUBR(4);
10910
10911         /* allocation size */
10912         CHECK_BYTE_COUNT_SUBR(4);
10913         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10914         COUNT_BYTES_SUBR(4);
10915
10916         /* File Attributes */
10917         CHECK_BYTE_COUNT_SUBR(2);
10918         offset = dissect_file_attributes(tvb, tree, offset, 2);
10919         *bcp -= 2;
10920
10921         /* ea length */
10922         CHECK_BYTE_COUNT_SUBR(4);
10923         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10924         COUNT_BYTES_SUBR(4);
10925
10926         *trunc = FALSE;
10927         return offset;
10928 }
10929
10930 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10931    as described in 4.2.16.2
10932 */
10933 static int
10934 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10935     int offset, guint16 *bcp, gboolean *trunc)
10936 {
10937         guint8 name_len;
10938         guint16 data_len;
10939         /* EA size */
10940
10941         CHECK_BYTE_COUNT_SUBR(4);
10942         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10943         COUNT_BYTES_SUBR(4);
10944
10945         while (*bcp > 0) {
10946                 proto_item *item;
10947                 proto_tree *subtree;
10948                 int start_offset = offset;
10949                 guint8 *name;
10950
10951                 item = proto_tree_add_text(
10952                         tree, tvb, offset, 0, "Extended Attribute");
10953                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10954
10955                 /* EA flags */
10956                 
10957                 CHECK_BYTE_COUNT_SUBR(1);
10958                 proto_tree_add_item(
10959                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10960                 COUNT_BYTES_SUBR(1);
10961
10962                 /* EA name length */
10963                 
10964                 name_len = tvb_get_guint8(tvb, offset);
10965
10966                 CHECK_BYTE_COUNT_SUBR(1);
10967                 proto_tree_add_item(
10968                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10969                 COUNT_BYTES_SUBR(1);
10970
10971                 /* EA data length */
10972
10973                 data_len = tvb_get_letohs(tvb, offset);
10974                 
10975                 CHECK_BYTE_COUNT_SUBR(2);
10976                 proto_tree_add_item(
10977                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10978                 COUNT_BYTES_SUBR(2);
10979
10980                 /* EA name */
10981
10982                 name = tvb_get_ephemeral_string(tvb, offset, name_len);
10983                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
10984
10985                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10986                 proto_tree_add_item(
10987                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10988                         TRUE);
10989                 COUNT_BYTES_SUBR(name_len + 1);
10990
10991                 /* EA data */
10992                 
10993                 CHECK_BYTE_COUNT_SUBR(data_len);
10994                 proto_tree_add_item(
10995                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10996                 COUNT_BYTES_SUBR(data_len);
10997
10998                 proto_item_set_len(item, offset - start_offset);
10999         }
11000
11001         *trunc = FALSE;
11002         return offset;
11003 }
11004
11005 /* this dissects the SMB_INFO_IS_NAME_VALID
11006    as described in 4.2.16.3
11007 */
11008 static int
11009 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11010     int offset, guint16 *bcp, gboolean *trunc)
11011 {
11012         smb_info_t *si = pinfo->private_data;
11013         int fn_len;
11014         const char *fn;
11015
11016         DISSECTOR_ASSERT(si);
11017
11018         /* file name */
11019         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11020         CHECK_STRING_SUBR(fn);
11021         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11022                 fn);
11023         COUNT_BYTES_SUBR(fn_len);
11024
11025         *trunc = FALSE;
11026         return offset;
11027 }
11028
11029 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11030    as described in 4.2.16.4
11031 */
11032 static int
11033 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11034     int offset, guint16 *bcp, gboolean *trunc)
11035 {
11036
11037         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11038         if (*trunc) {
11039           return offset;
11040         }
11041
11042         /* File Attributes */
11043         CHECK_BYTE_COUNT_SUBR(4);
11044         offset = dissect_file_attributes(tvb, tree, offset, 4);
11045         *bcp -= 4;
11046
11047         *trunc = FALSE;
11048         return offset;
11049 }
11050
11051 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11052    as described in 4.2.16.5
11053 */
11054 int
11055 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11056     int offset, guint16 *bcp, gboolean *trunc)
11057 {
11058         /* allocation size */
11059         CHECK_BYTE_COUNT_SUBR(8);
11060         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11061         COUNT_BYTES_SUBR(8);
11062
11063         /* end of file */
11064         CHECK_BYTE_COUNT_SUBR(8);
11065         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11066         COUNT_BYTES_SUBR(8);
11067
11068         /* number of links */
11069         CHECK_BYTE_COUNT_SUBR(4);
11070         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11071         COUNT_BYTES_SUBR(4);
11072
11073         /* delete pending */
11074         CHECK_BYTE_COUNT_SUBR(1);
11075         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11076         COUNT_BYTES_SUBR(1);
11077
11078         /* is directory */
11079         CHECK_BYTE_COUNT_SUBR(1);
11080         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11081         COUNT_BYTES_SUBR(1);
11082
11083         *trunc = FALSE;
11084         return offset;
11085 }
11086
11087 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
11088 */
11089 int
11090 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11091     int offset, guint16 *bcp, gboolean *trunc)
11092 {
11093         /* file id */
11094         CHECK_BYTE_COUNT_SUBR(8);
11095         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11096         COUNT_BYTES_SUBR(8);
11097
11098         *trunc = FALSE;
11099         return offset;
11100 }
11101
11102 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
11103 */
11104 int
11105 dissect_qfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11106     int offset, guint16 *bcp, gboolean *trunc)
11107 {
11108         /* file id */
11109         CHECK_BYTE_COUNT_SUBR(8);
11110         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, TRUE);
11111         COUNT_BYTES_SUBR(8);
11112
11113         *trunc = FALSE;
11114         return offset;
11115 }
11116
11117 /* this dissects the SMB_QUERY_FILE_MODE_INFO
11118 */
11119 int
11120 dissect_qfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11121     int offset, guint16 *bcp, gboolean *trunc)
11122 {
11123         /* mode */
11124         CHECK_BYTE_COUNT_SUBR(4);
11125         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, TRUE);
11126         COUNT_BYTES_SUBR(4);
11127
11128         *trunc = FALSE;
11129         return offset;
11130 }
11131
11132 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
11133 */
11134 int
11135 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11136     int offset, guint16 *bcp, gboolean *trunc)
11137 {
11138         /* alignment */
11139         CHECK_BYTE_COUNT_SUBR(4);
11140         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11141         COUNT_BYTES_SUBR(4);
11142
11143         *trunc = FALSE;
11144         return offset;
11145 }
11146
11147 /* this dissects the SMB_QUERY_FILE_EA_INFO
11148    as described in 4.2.16.6
11149 */
11150 int
11151 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11152     int offset, guint16 *bcp, gboolean *trunc)
11153 {
11154         /* ea length */
11155         CHECK_BYTE_COUNT_SUBR(4);
11156         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11157         COUNT_BYTES_SUBR(4);
11158
11159         *trunc = FALSE;
11160         return offset;
11161 }
11162
11163 /* this dissects the SMB_QUERY_FILE_ALLOCATION_INFO
11164 */
11165 int
11166 dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11167     int offset, guint16 *bcp, gboolean *trunc)
11168 {
11169         /* allocation size */
11170         CHECK_BYTE_COUNT_SUBR(8);
11171         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11172         COUNT_BYTES_SUBR(8);
11173
11174         *trunc = FALSE;
11175         return offset;
11176 }
11177
11178 /* this dissects the SMB_QUERY_FILE_ENDOFFILE_INFO
11179 */
11180 int
11181 dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11182     int offset, guint16 *bcp, gboolean *trunc)
11183 {
11184         /* end of file */
11185         CHECK_BYTE_COUNT_SUBR(8);
11186         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11187         COUNT_BYTES_SUBR(8);
11188
11189         *trunc = FALSE;
11190         return offset;
11191 }
11192
11193 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11194    as described in 4.2.16.7
11195    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11196    as described in 4.2.16.9
11197 */
11198 int
11199 dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11200     int offset, guint16 *bcp, gboolean *trunc)
11201 {
11202         smb_info_t *si = pinfo->private_data;
11203         int fn_len;
11204         const char *fn;
11205
11206         DISSECTOR_ASSERT(si);
11207
11208         /* file name len */
11209         CHECK_BYTE_COUNT_SUBR(4);
11210         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11211         COUNT_BYTES_SUBR(4);
11212
11213         /* file name */
11214         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11215         CHECK_STRING_SUBR(fn);
11216         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11217                 fn);
11218         COUNT_BYTES_SUBR(fn_len);
11219
11220         *trunc = FALSE;
11221         return offset;
11222 }
11223
11224 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11225    but not as described in 4.2.16.8 since CNIA spec is wrong 
11226 */
11227 static int
11228 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11229     int offset, guint16 *bcp, gboolean *trunc)
11230 {
11231         smb_info_t *si;
11232         guint32 fn_len;
11233         const char *fn;
11234
11235         si = (smb_info_t *)pinfo->private_data;
11236
11237         DISSECTOR_ASSERT(si);
11238
11239         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11240         if (*trunc) {
11241           return offset;
11242         }
11243
11244         /* File Attributes */
11245         CHECK_BYTE_COUNT_SUBR(4);
11246         offset = dissect_file_attributes(tvb, tree, offset, 4);
11247         *bcp -= 4;
11248
11249         /* 4 pad bytes */
11250         offset+=4;
11251         *bcp -= 4;
11252
11253         /* allocation size */
11254         CHECK_BYTE_COUNT_SUBR(8);
11255         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11256         COUNT_BYTES_SUBR(8);
11257
11258         /* end of file */
11259         CHECK_BYTE_COUNT_SUBR(8);
11260         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11261         COUNT_BYTES_SUBR(8);
11262
11263         /* number of links */
11264         CHECK_BYTE_COUNT_SUBR(4);
11265         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11266         COUNT_BYTES_SUBR(4);
11267
11268         /* delete pending */
11269         CHECK_BYTE_COUNT_SUBR(1);
11270         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11271         COUNT_BYTES_SUBR(1);
11272
11273         /* is directory */
11274         CHECK_BYTE_COUNT_SUBR(1);
11275         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11276         COUNT_BYTES_SUBR(1);
11277
11278         /* 2 pad bytes */
11279         offset+=2;
11280         *bcp -= 2;
11281
11282         /* ea length */
11283         CHECK_BYTE_COUNT_SUBR(4);
11284         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11285         COUNT_BYTES_SUBR(4);
11286
11287         /* file name len */
11288         CHECK_BYTE_COUNT_SUBR(4);
11289         fn_len = (guint32)tvb_get_letohl(tvb, offset);
11290         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11291         COUNT_BYTES_SUBR(4);
11292
11293
11294         /* file name */
11295         CHECK_BYTE_COUNT_SUBR(fn_len);
11296         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
11297         if (fn != NULL) {
11298                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11299                         fn);
11300                 COUNT_BYTES_SUBR(fn_len);
11301         }
11302
11303
11304         if (*trunc)
11305                 return offset;
11306
11307         return offset;
11308 }
11309
11310 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11311    as described in 4.2.16.10
11312 */
11313 int
11314 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
11315     int offset, guint16 *bcp, gboolean *trunc, int unicode)
11316 {
11317         proto_item *item;
11318         proto_tree *tree;
11319         int old_offset;
11320         guint32 neo;
11321         int fn_len;
11322         const char *fn;
11323         int padcnt;
11324
11325
11326         for (;;) {
11327                 old_offset = offset;
11328
11329                 /* next entry offset */
11330                 CHECK_BYTE_COUNT_SUBR(4);
11331                 if(parent_tree){
11332                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11333                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11334                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11335                 } else {
11336                         item = NULL;
11337                         tree = NULL;
11338                 }
11339
11340                 neo = tvb_get_letohl(tvb, offset);
11341                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11342                 COUNT_BYTES_SUBR(4);
11343
11344                 /* stream name len */
11345                 CHECK_BYTE_COUNT_SUBR(4);
11346                 fn_len = tvb_get_letohl(tvb, offset);
11347                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11348                 COUNT_BYTES_SUBR(4);
11349
11350                 /* stream size */
11351                 CHECK_BYTE_COUNT_SUBR(8);
11352                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11353                 COUNT_BYTES_SUBR(8);
11354
11355                 /* allocation size */
11356                 CHECK_BYTE_COUNT_SUBR(8);
11357                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11358                 COUNT_BYTES_SUBR(8);
11359
11360                 /* stream name */
11361                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
11362                 CHECK_STRING_SUBR(fn);
11363                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11364                         fn);
11365                 COUNT_BYTES_SUBR(fn_len);
11366
11367                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
11368                 proto_item_set_len(item, offset-old_offset);
11369
11370                 if (neo == 0)
11371                         break;  /* no more structures */
11372
11373                 /* skip to next structure */
11374                 padcnt = (old_offset + neo) - offset;
11375                 if (padcnt < 0) {
11376                         /*
11377                          * XXX - this is bogus; flag it?
11378                          */
11379                         padcnt = 0;
11380                 }
11381                 if (padcnt != 0) {
11382                         CHECK_BYTE_COUNT_SUBR(padcnt);
11383                         COUNT_BYTES_SUBR(padcnt);
11384                 }
11385         }
11386
11387         *trunc = FALSE;
11388         return offset;
11389 }
11390
11391 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11392    as described in 4.2.16.11
11393 */
11394 int
11395 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11396     int offset, guint16 *bcp, gboolean *trunc)
11397 {
11398         /* compressed file size */
11399         CHECK_BYTE_COUNT_SUBR(8);
11400         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11401         COUNT_BYTES_SUBR(8);
11402
11403         /* compression format */
11404         CHECK_BYTE_COUNT_SUBR(2);
11405         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11406         COUNT_BYTES_SUBR(2);
11407
11408         /* compression unit shift */
11409         CHECK_BYTE_COUNT_SUBR(1);
11410         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11411         COUNT_BYTES_SUBR(1);
11412
11413         /* compression chunk shift */
11414         CHECK_BYTE_COUNT_SUBR(1);
11415         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11416         COUNT_BYTES_SUBR(1);
11417
11418         /* compression cluster shift */
11419         CHECK_BYTE_COUNT_SUBR(1);
11420         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11421         COUNT_BYTES_SUBR(1);
11422
11423         /* 3 reserved bytes */
11424         CHECK_BYTE_COUNT_SUBR(3);
11425         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11426         COUNT_BYTES_SUBR(3);
11427
11428         *trunc = FALSE;
11429         return offset;
11430 }
11431
11432 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11433
11434 static const value_string unix_file_type_vals[] = {
11435         { 0, "File" },
11436         { 1, "Directory" },
11437         { 2, "Symbolic link" },
11438         { 3, "Character device" },
11439         { 4, "Block device" },
11440         { 5, "FIFO" },
11441         { 6, "Socket" },
11442         { 0, NULL }
11443 };
11444
11445 static int
11446 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11447                   int offset, guint16 *bcp, gboolean *trunc)
11448 {
11449         /* End of file (file size) */
11450         CHECK_BYTE_COUNT_SUBR(8);
11451         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11452         COUNT_BYTES_SUBR(8);
11453
11454         /* Number of bytes */
11455         CHECK_BYTE_COUNT_SUBR(8);
11456         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11457         COUNT_BYTES_SUBR(8);
11458
11459         /* Last status change */
11460         CHECK_BYTE_COUNT_SUBR(8);
11461         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11462         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
11463
11464         /* Last access time */
11465         CHECK_BYTE_COUNT_SUBR(8);
11466         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11467         *bcp -= 8;
11468
11469         /* Last modification time */
11470         CHECK_BYTE_COUNT_SUBR(8);
11471         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11472         *bcp -= 8;
11473
11474         /* File owner uid */
11475         CHECK_BYTE_COUNT_SUBR(8);
11476         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11477         COUNT_BYTES_SUBR(8);
11478
11479         /* File group gid */
11480         CHECK_BYTE_COUNT_SUBR(8);
11481         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11482         COUNT_BYTES_SUBR(8);
11483
11484         /* File type */
11485         CHECK_BYTE_COUNT_SUBR(4);
11486         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11487         COUNT_BYTES_SUBR(4);
11488
11489         /* Major device number */
11490         CHECK_BYTE_COUNT_SUBR(8);
11491         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11492         COUNT_BYTES_SUBR(8);
11493
11494         /* Minor device number */
11495         CHECK_BYTE_COUNT_SUBR(8);
11496         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11497         COUNT_BYTES_SUBR(8);
11498
11499         /* Unique id */
11500         CHECK_BYTE_COUNT_SUBR(8);
11501         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11502         COUNT_BYTES_SUBR(8);
11503
11504         /* Permissions */
11505         CHECK_BYTE_COUNT_SUBR(8);
11506         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11507         COUNT_BYTES_SUBR(8);
11508
11509         /* Nlinks */
11510         CHECK_BYTE_COUNT_SUBR(8);
11511         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11512         COUNT_BYTES_SUBR(8);
11513
11514         /* Sometimes there is one extra byte in the data field which I
11515            guess could be padding, but we are only using 4 or 8 byte
11516            data types so this is a bit confusing. -tpot */
11517
11518         *trunc = FALSE;
11519         return offset;
11520 }
11521
11522 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11523
11524 static int
11525 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11526                   int offset, guint16 *bcp, gboolean *trunc)
11527 {
11528         smb_info_t *si = pinfo->private_data;
11529         const char *fn;
11530         int fn_len;
11531
11532         DISSECTOR_ASSERT(si);
11533
11534         /* Link destination */
11535
11536         fn = get_unicode_or_ascii_string(
11537                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11538
11539         CHECK_STRING_SUBR(fn);
11540         proto_tree_add_string(
11541                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11542         COUNT_BYTES_SUBR(fn_len);
11543
11544         *trunc = FALSE;
11545         return offset;
11546 }
11547
11548 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
11549 */
11550 int
11551 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb, 
11552     packet_info *pinfo, proto_tree *tree,
11553     int offset, guint16 *bcp, gboolean *trunc)
11554 {
11555
11556         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11557         if (*trunc) {
11558           return offset;
11559         }
11560
11561         /* allocation size */
11562         CHECK_BYTE_COUNT_SUBR(8);
11563         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11564         COUNT_BYTES_SUBR(8);
11565
11566         /* end of file */
11567         CHECK_BYTE_COUNT_SUBR(8);
11568         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11569         COUNT_BYTES_SUBR(8);
11570
11571         /* File Attributes */
11572         CHECK_BYTE_COUNT_SUBR(4);
11573         offset = dissect_file_attributes(tvb, tree, offset, 4);
11574         *bcp -= 4;
11575
11576         /* Unknown, possibly count of network accessors ... */
11577         CHECK_BYTE_COUNT_SUBR(4);
11578         proto_tree_add_item(tree, hf_smb_network_unknown, tvb, offset, 4, TRUE);
11579         COUNT_BYTES_SUBR(4);
11580
11581         *trunc = FALSE;
11582         return offset;
11583 }
11584
11585 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
11586 */
11587 int
11588 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb, 
11589     packet_info *pinfo _U_, proto_tree *tree,
11590     int offset, guint16 *bcp, gboolean *trunc)
11591 {
11592         /* attribute */
11593         CHECK_BYTE_COUNT_SUBR(4);
11594         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, TRUE);
11595         COUNT_BYTES_SUBR(4);
11596
11597         /* reparse tag */
11598         CHECK_BYTE_COUNT_SUBR(4);
11599         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, TRUE);
11600         COUNT_BYTES_SUBR(4);
11601
11602         *trunc = FALSE;
11603         return offset;
11604 }
11605
11606 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11607    as described in 4.2.19.2
11608 */
11609 static int
11610 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11611     int offset, guint16 *bcp, gboolean *trunc)
11612 {
11613         /* marked for deletion? */
11614         CHECK_BYTE_COUNT_SUBR(1);
11615         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11616         COUNT_BYTES_SUBR(1);
11617
11618         *trunc = FALSE;
11619         return offset;
11620 }
11621
11622 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11623    as described in 4.2.19.3
11624 */
11625 static int
11626 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11627     int offset, guint16 *bcp, gboolean *trunc)
11628 {
11629         /* file allocation size */
11630         CHECK_BYTE_COUNT_SUBR(8);
11631         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11632         COUNT_BYTES_SUBR(8);
11633
11634         *trunc = FALSE;
11635         return offset;
11636 }
11637
11638 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11639    as described in 4.2.19.4
11640 */
11641 static int
11642 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11643     int offset, guint16 *bcp, gboolean *trunc)
11644 {
11645         /* file end of file offset */
11646         CHECK_BYTE_COUNT_SUBR(8);
11647         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11648         COUNT_BYTES_SUBR(8);
11649
11650         *trunc = FALSE;
11651         return offset;
11652 }
11653
11654 /* Set File Rename Info */
11655
11656 static const true_false_string tfs_smb_replace = {
11657         "Remove target file if it exists",
11658         "Do NOT remove target file if it exists",
11659 };
11660
11661 static int
11662 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11663                     int offset, guint16 *bcp, gboolean *trunc)
11664 {
11665         smb_info_t *si = pinfo->private_data;
11666         const char *fn;
11667         guint32 target_name_len;
11668         int fn_len;
11669
11670         DISSECTOR_ASSERT(si);
11671
11672         /* Replace flag */
11673         CHECK_BYTE_COUNT_SUBR(4);
11674         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
11675         COUNT_BYTES_SUBR(4);
11676
11677         /* Root directory handle */
11678         CHECK_BYTE_COUNT_SUBR(4);
11679         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
11680         COUNT_BYTES_SUBR(4);
11681
11682         /* Target name length */
11683         CHECK_BYTE_COUNT_SUBR(4);
11684         target_name_len = tvb_get_letohl(tvb, offset);
11685         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
11686         COUNT_BYTES_SUBR(4);
11687
11688         /* Target name */
11689         fn_len = target_name_len;
11690         fn = get_unicode_or_ascii_string(
11691                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11692
11693         CHECK_STRING_SUBR(fn);
11694         proto_tree_add_string(
11695                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
11696         COUNT_BYTES_SUBR(fn_len);
11697
11698         *trunc = FALSE;
11699         return offset;
11700 }
11701
11702 static int
11703 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11704                     int offset, guint16 *bcp, gboolean *trunc)
11705 {
11706         smb_info_t *si = pinfo->private_data;
11707 /*      const char *fn;*/
11708 /*      guint32 target_name_len;*/
11709 /*      int fn_len;*/
11710
11711         DISSECTOR_ASSERT(si);
11712
11713         /* Disposition flags */
11714         CHECK_BYTE_COUNT_SUBR(1);
11715         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, TRUE);
11716         COUNT_BYTES_SUBR(1);
11717
11718         *trunc = FALSE;
11719         return offset;
11720 }
11721
11722 int
11723 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11724                     int offset, guint16 *bcp, gboolean *trunc)
11725 {
11726         smb_info_t *si = pinfo->private_data;
11727
11728         DISSECTOR_ASSERT(si);
11729
11730         /* pipe info flag */
11731         CHECK_BYTE_COUNT_SUBR(1);
11732         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, TRUE);
11733         COUNT_BYTES_SUBR(1);
11734
11735         *trunc = FALSE;
11736         return offset;
11737 }
11738
11739 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11740   TRANS2_QUERY_FILE_INFORMATION*/
11741 static int
11742 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11743     int offset, guint16 *bcp)
11744 {
11745         smb_info_t *si;
11746         gboolean trunc;
11747
11748         if(!*bcp){
11749                 return offset;
11750         }
11751
11752         si = (smb_info_t *)pinfo->private_data;
11753         DISSECTOR_ASSERT(si);
11754
11755         switch(si->info_level){
11756         case 1:         /*Info Standard*/
11757                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11758                     &trunc);
11759                 break;
11760                 
11761         case 2:         /*Info Query EA Size*/
11762                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11763                     &trunc);
11764                 break;
11765         case 3:         /*Info Query EAs From List*/
11766         case 4:         /*Info Query All EAs*/
11767                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11768                     &trunc);
11769                 break;
11770         case 6:         /*Info Is Name Valid*/
11771                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11772                     &trunc);
11773                 break;
11774         case 0x0101:    /*Query File Basic Info*/
11775         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11776                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11777                     &trunc);
11778                 break;
11779         case 0x0102:    /*Query File Standard Info*/
11780         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11781                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
11782                     &trunc);
11783                 break;
11784         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
11785                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
11786                     &trunc);
11787                 break;
11788         case 0x0103:    /*Query File EA Info*/
11789         case 1007:      /* SMB_FILE_EA_INFORMATION */
11790                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
11791                     &trunc);
11792                 break;
11793         case 0x0104:    /*Query File Name Info*/
11794         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11795                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
11796                     &trunc);
11797                 break;
11798         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
11799                 offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
11800                     &trunc);
11801                 break;
11802         case 1016:      /* SMB_FILE_MODE_INFORMATION */
11803                 offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
11804                     &trunc);
11805                 break;
11806         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
11807                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
11808                     &trunc);
11809                 break;
11810         case 0x0107:    /*Query File All Info*/
11811         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11812                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
11813                     &trunc);
11814                 break;
11815         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
11816                 offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
11817                     &trunc);
11818                 break;
11819         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
11820                 offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
11821                     &trunc);
11822                 break;
11823         case 0x0108:    /*Query File Alt File Info*/
11824         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11825                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
11826                     &trunc);
11827                 break;
11828         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11829                 si->unicode = TRUE;
11830         case 0x0109:    /*Query File Stream Info*/
11831                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
11832                     &trunc, si->unicode);
11833                 break;
11834         case 0x010b:    /*Query File Compression Info*/
11835         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11836                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
11837                     &trunc);
11838                 break;
11839         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
11840                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
11841                 break;
11842         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
11843                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
11844                 break;
11845         case 0x0200:    /* Query File Unix Basic*/
11846                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11847                                            &trunc);
11848                 break;
11849         case 0x0201:    /* Query File Unix Link*/
11850                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11851                                            &trunc);
11852                 break;
11853         case 0x0202:    /* Query File Unix HardLink*/
11854                 /* XXX add this from the SNIA doc */
11855                 break;
11856         }
11857
11858         return offset;
11859 }
11860
11861 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11862   TRANS2_SET_FILE_INFORMATION*/
11863 static int
11864 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11865     int offset, guint16 *bcp)
11866 {
11867         smb_info_t *si;
11868         gboolean trunc;
11869
11870         if(!*bcp){
11871                 return offset;
11872         }
11873
11874         si = (smb_info_t *)pinfo->private_data;
11875         DISSECTOR_ASSERT(si);
11876
11877         switch(si->info_level){
11878         case 1:         /*Info Standard*/
11879                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11880                     &trunc);
11881                 break;
11882         case 2:         /*Info Query EA Size*/
11883                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11884                     &trunc);
11885                 break;
11886         case 4:         /*Info Query All EAs*/
11887                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11888                     &trunc);
11889                 break;
11890         case 0x0101:    /*Set File Basic Info*/
11891         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11892                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11893                     &trunc);
11894                 break;
11895         case 0x0102:    /*Set File Disposition Info*/
11896                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11897                     &trunc);
11898                 break;
11899         case 0x0103:    /*Set File Allocation Info*/
11900                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11901                     &trunc);
11902                 break;
11903         case 0x0104:    /*Set End Of File Info*/
11904                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11905                     &trunc);
11906                 break;
11907         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11908                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11909                     &trunc);
11910                 break;
11911         case 0x0201:    /*Set File Unix Link.  Same as query. */
11912                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11913                     &trunc);
11914                 break;
11915         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11916                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11917                     &trunc);
11918                 break;
11919         case 1010:      /* Set File Rename */
11920                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
11921                     &trunc);
11922                 break;
11923         case 1013: /* Set Disposition Information */
11924                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
11925                     &trunc);
11926                 break;
11927         case 1023: /* Set Pipe Info */
11928                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
11929                     &trunc);
11930                 break;
11931         case 1014:
11932         case 1016:
11933         case 1019:
11934         case 1020:
11935         case 1025:
11936         case 1029:
11937         case 1032:
11938         case 1039:
11939         case 1040:
11940                 /* XXX: TODO, extra levels discovered by tridge */
11941                 break;
11942         }
11943
11944         return offset;
11945 }
11946
11947
11948 static const true_false_string tfs_quota_flags_deny_disk = {
11949         "DENY DISK SPACE for users exceeding quota limit",
11950         "Do NOT deny disk space for users exceeding quota limit"
11951 };
11952 static const true_false_string tfs_quota_flags_log_limit = {
11953         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11954         "Do NOT log event when a user exceeds their quota limit"
11955 };
11956 static const true_false_string tfs_quota_flags_log_warning = {
11957         "LOG EVENT when a user exceeds their WARNING LEVEL",
11958         "Do NOT log event when a user exceeds their warning level"
11959 };
11960 static const true_false_string tfs_quota_flags_enabled = {
11961         "Quotas are ENABLED of this fs",
11962         "Quotas are NOT enabled on this fs"
11963 };
11964 static void
11965 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11966 {
11967         guint8 mask;
11968         proto_item *item = NULL;
11969         proto_tree *tree = NULL;
11970
11971         mask = tvb_get_guint8(tvb, offset);
11972
11973         if(parent_tree){
11974                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11975                         "Quota Flags: 0x%02x %s", mask,
11976                         mask?"Enabled":"Disabled");
11977                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11978         }
11979
11980         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11981                 tvb, offset, 1, mask);
11982         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11983                 tvb, offset, 1, mask);
11984         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11985                 tvb, offset, 1, mask);
11986
11987         if(mask && (!(mask&0x01))){
11988                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11989                         tvb, offset, 1, 0x01);
11990         } else {
11991                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11992                         tvb, offset, 1, mask);
11993         }
11994
11995 }
11996
11997 int
11998 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11999 {
12000         /* first 24 bytes are unknown */
12001         CHECK_BYTE_COUNT_TRANS_SUBR(24);
12002         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12003                     offset, 24, TRUE);
12004         COUNT_BYTES_TRANS_SUBR(24);
12005
12006         /* number of bytes for quota warning */
12007         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12008         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
12009         COUNT_BYTES_TRANS_SUBR(8);
12010
12011         /* number of bytes for quota limit */
12012         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12013         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
12014         COUNT_BYTES_TRANS_SUBR(8);
12015
12016         /* one byte of quota flags */
12017         CHECK_BYTE_COUNT_TRANS_SUBR(1);
12018         dissect_quota_flags(tvb, tree, offset);
12019         COUNT_BYTES_TRANS_SUBR(1);
12020
12021         /* these 7 bytes are unknown */
12022         CHECK_BYTE_COUNT_TRANS_SUBR(7);
12023         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12024                     offset, 7, TRUE);
12025         COUNT_BYTES_TRANS_SUBR(7);
12026
12027         return offset;
12028 }
12029
12030 static int
12031 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
12032     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
12033 {
12034         proto_item *item = NULL;
12035         proto_tree *tree = NULL;
12036         smb_info_t *si;
12037
12038         si = (smb_info_t *)pinfo->private_data;
12039         DISSECTOR_ASSERT(si);
12040
12041         if(parent_tree){
12042                 tvb_ensure_bytes_exist(tvb, offset, dc);
12043                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12044                                 "%s Data",
12045                                 val_to_str(subcmd, trans2_cmd_vals,
12046                                                 "Unknown (0x%02x)"));
12047                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12048         }
12049
12050         switch(subcmd){
12051         case 0x00:      /*TRANS2_OPEN2*/
12052                 /* XXX dont know how to decode FEAList */
12053                 break;
12054         case 0x01:      /*TRANS2_FIND_FIRST2*/
12055                 /* XXX dont know how to decode FEAList */
12056                 break;
12057         case 0x02:      /*TRANS2_FIND_NEXT2*/
12058                 /* XXX dont know how to decode FEAList */
12059                 break;
12060         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12061                 /* no data field in this request */
12062                 break;
12063         case 0x04:      /* TRANS2_SET_QUOTA */
12064                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
12065                 break;
12066         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12067                 /* no data field in this request */
12068                 /*
12069                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12070                  * Extensions Version 3.0, Document Version 1.11,
12071                  * July 19, 1990" says there may be "Additional
12072                  * FileInfoLevel dependent information" here.
12073                  *
12074                  * Was that just a cut-and-pasteo?
12075                  * TRANS2_SET_PATH_INFORMATION *does* have that information
12076                  * here.
12077                  */
12078                 break;
12079         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12080                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12081                 break;
12082         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12083                 /* no data field in this request */
12084                 /*
12085                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12086                  * Extensions Version 3.0, Document Version 1.11,
12087                  * July 19, 1990" says there may be "Additional
12088                  * FileInfoLevel dependent information" here.
12089                  *
12090                  * Was that just a cut-and-pasteo?
12091                  * TRANS2_SET_FILE_INFORMATION *does* have that information
12092                  * here.
12093                  */
12094                 break;
12095         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12096                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12097                 break;
12098         case 0x09:      /*TRANS2_FSCTL*/
12099                 /*XXX dont know how to decode this yet */
12100
12101                 /*
12102                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12103                  * Extensions Version 3.0, Document Version 1.11,
12104                  * July 19, 1990" says this this contains a
12105                  * "File system specific data block".  (That means we
12106                  * may not be able to dissect it in any case.)
12107                  */
12108                 break;
12109         case 0x0a:      /*TRANS2_IOCTL2*/
12110                 /*XXX dont know how to decode this yet */
12111
12112                 /*
12113                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12114                  * Extensions Version 3.0, Document Version 1.11,
12115                  * July 19, 1990" says this this contains a
12116                  * "Device/function specific data block".  (That
12117                  * means we may not be able to dissect it in any case.)
12118                  */
12119                 break;
12120         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12121                 /*XXX dont know how to decode this yet */
12122
12123                 /*
12124                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12125                  * Extensions Version 3.0, Document Version 1.11,
12126                  * July 19, 1990" says this this contains "additional
12127                  * level dependent match data".
12128                  */
12129                 break;
12130         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12131                 /*XXX dont know how to decode this yet */
12132
12133                 /*
12134                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12135                  * Extensions Version 3.0, Document Version 1.11,
12136                  * July 19, 1990" says this this contains "additional
12137                  * level dependent monitor information".
12138                  */
12139                 break;
12140         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12141                 /* XXX optional FEAList, unknown what FEAList looks like*/
12142                 break;
12143         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12144                 /*XXX dont know how to decode this yet */
12145                 break;
12146         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12147                 /* no data field in this request */
12148                 break;
12149         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12150                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
12151                 break;
12152         }
12153
12154         /* ooops there were data we didnt know how to process */
12155         if(dc != 0){
12156                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12157                 offset += dc;
12158         }
12159
12160         return offset;
12161 }
12162
12163
12164 static void
12165 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
12166     proto_tree *tree)
12167 {
12168         int i;
12169         int offset;
12170         guint length;
12171
12172         /*
12173          * Show the setup words.
12174          */
12175         if (s_tvb != NULL) {
12176                 length = tvb_reported_length(s_tvb);
12177                 for (i = 0, offset = 0; length >= 2;
12178                     i++, offset += 2, length -= 2) {
12179                         /*
12180                          * XXX - add a setup word filterable field?
12181                          */
12182                         proto_tree_add_text(tree, s_tvb, offset, 2,
12183                             "Setup Word %d: 0x%04x", i,
12184                             tvb_get_letohs(s_tvb, offset));
12185                 }
12186         }
12187
12188         /*
12189          * Show the parameters, if any.
12190          */
12191         if (p_tvb != NULL) {
12192                 length = tvb_reported_length(p_tvb);
12193                 if (length != 0) {
12194                         proto_tree_add_text(tree, p_tvb, 0, length,
12195                             "Parameters: %s",
12196                             tvb_bytes_to_str(p_tvb, 0, length));
12197                 }
12198         }
12199
12200         /*
12201          * Show the data, if any.
12202          */
12203         if (d_tvb != NULL) {
12204                 length = tvb_reported_length(d_tvb);
12205                 if (length != 0) {
12206                         proto_tree_add_text(tree, d_tvb, 0, length,
12207                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
12208                 }
12209         }
12210 }
12211
12212 /* This routine handles the following 4 calls
12213    Transaction  0x25
12214    Transaction Secondary 0x26
12215    Transaction2 0x32
12216    Transaction2 Secondary 0x33
12217 */
12218 static int
12219 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12220 {
12221         guint8 wc, sc=0;
12222         int so=offset;
12223         int sl=0;
12224         int spo=offset;
12225         int spc=0;
12226         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
12227         int subcmd = -1;
12228         guint32 to;
12229         int an_len;
12230         const char *an = NULL;
12231         smb_info_t *si;
12232         smb_transact2_info_t *t2i;
12233         smb_transact_info_t *tri;
12234         guint16 bc;
12235         int padcnt;
12236         gboolean dissected_trans;
12237
12238         si = (smb_info_t *)pinfo->private_data;
12239         DISSECTOR_ASSERT(si);
12240
12241         WORD_COUNT;
12242
12243         if(wc==8){
12244                 /*secondary client request*/
12245
12246                 /* total param count, only a 16bit integer here*/
12247                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12248                 offset += 2;
12249
12250                 /* total data count , only 16bit integer here*/
12251                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12252                 offset += 2;
12253
12254                 /* param count */
12255                 pc = tvb_get_letohs(tvb, offset);
12256                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12257                 offset += 2;
12258
12259                 /* param offset */
12260                 po = tvb_get_letohs(tvb, offset);
12261                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12262                 offset += 2;
12263
12264                 /* param disp */
12265                 pd = tvb_get_letohs(tvb, offset);
12266                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12267                 offset += 2;
12268
12269                 /* data count */
12270                 dc = tvb_get_letohs(tvb, offset);
12271                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12272                 offset += 2;
12273
12274                 /* data offset */
12275                 od = tvb_get_letohs(tvb, offset);
12276                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12277                 offset += 2;
12278
12279                 /* data disp */
12280                 dd = tvb_get_letohs(tvb, offset);
12281                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12282                 offset += 2;
12283
12284                 if(si->cmd==SMB_COM_TRANSACTION2){
12285                         guint16 fid;
12286
12287                         /* fid */
12288                         fid = tvb_get_letohs(tvb, offset);
12289                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
12290
12291                         offset += 2;
12292                 }
12293
12294                 /* There are no setup words. */
12295                 so = offset;
12296                 sc = 0;
12297                 sl = 0;
12298         } else {
12299                 /* it is not a secondary request */
12300
12301                 /* total param count , only a 16 bit integer here*/
12302                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12303                 offset += 2;
12304
12305                 /* total data count , only 16bit integer here*/
12306                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12307                 offset += 2;
12308
12309                 /* max param count , only 16bit integer here*/
12310                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12311                 offset += 2;
12312
12313                 /* max data count, only 16bit integer here*/
12314                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12315                 offset += 2;
12316
12317                 /* max setup count, only 16bit integer here*/
12318                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12319                 offset += 1;
12320
12321                 /* reserved byte */
12322                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12323                 offset += 1;
12324
12325                 /* transaction flags */
12326                 tf = dissect_transaction_flags(tvb, tree, offset);
12327                 offset += 2;
12328
12329                 /* timeout */
12330                 to = tvb_get_letohl(tvb, offset);
12331                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
12332                 offset += 4;
12333
12334                 /* 2 reserved bytes */
12335                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12336                 offset += 2;
12337
12338                 /* param count */
12339                 pc = tvb_get_letohs(tvb, offset);
12340                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12341                 offset += 2;
12342
12343                 /* param offset */
12344                 po = tvb_get_letohs(tvb, offset);
12345                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12346                 offset += 2;
12347
12348                 /* param displacement is zero here */
12349                 pd = 0;
12350
12351                 /* data count */
12352                 dc = tvb_get_letohs(tvb, offset);
12353                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12354                 offset += 2;
12355
12356                 /* data offset */
12357                 od = tvb_get_letohs(tvb, offset);
12358                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12359                 offset += 2;
12360
12361                 /* data displacement is zero here */
12362                 dd = 0;
12363
12364                 /* setup count */
12365                 sc = tvb_get_guint8(tvb, offset);
12366                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12367                 offset += 1;
12368
12369                 /* reserved byte */
12370                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12371                 offset += 1;
12372
12373                 /* this is where the setup bytes, if any start */
12374                 so = offset;
12375                 sl = sc*2;
12376
12377                 /* if there were any setup bytes, decode them */
12378                 if(sc){
12379                         switch(si->cmd){
12380
12381                         case SMB_COM_TRANSACTION2:
12382                                 /* TRANSACTION2 only has one setup word and
12383                                    that is the subcommand code.
12384
12385                                    XXX - except for TRANS2_FSCTL
12386                                    and TRANS2_IOCTL. */
12387                                 subcmd = tvb_get_letohs(tvb, offset);
12388                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12389                                     tvb, offset, 2, subcmd);
12390                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12391                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12392                                             val_to_str(subcmd, trans2_cmd_vals,
12393                                                 "Unknown (0x%02x)"));
12394                                 }
12395                                 if (!si->unidir) {
12396                                         if(!pinfo->fd->flags.visited && si->sip){
12397                                                 /*
12398                                                  * Allocate a new
12399                                                  * smb_transact2_info_t
12400                                                  * structure.
12401                                                  */
12402                                                 t2i = se_alloc(sizeof(smb_transact2_info_t));
12403                                                 t2i->subcmd = subcmd;
12404                                                 t2i->info_level = -1;
12405                                                 t2i->resume_keys = FALSE;
12406                                                 si->sip->extra_info = t2i;
12407                                                 si->sip->extra_info_type = SMB_EI_T2I;
12408                                         }
12409                                 }
12410
12411                                 /*
12412                                  * XXX - process TRANS2_FSCTL and
12413                                  * TRANS2_IOCTL setup words here.
12414                                  */
12415                                 break;
12416
12417                         case SMB_COM_TRANSACTION:
12418                                 /* TRANSACTION setup words processed below */
12419                                 break;
12420                         }
12421
12422                         offset += sl;
12423                 }
12424         }
12425
12426         BYTE_COUNT;
12427
12428         if(wc!=8){
12429                 /* primary request */
12430                 /* name is NULL if transaction2 */
12431                 if(si->cmd == SMB_COM_TRANSACTION){
12432                         /* Transaction Name */
12433                         an = get_unicode_or_ascii_string(tvb, &offset,
12434                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12435                         if (an == NULL)
12436                                 goto endofcommand;
12437                         tvb_ensure_bytes_exist(tvb, offset, an_len);
12438                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12439                                 offset, an_len, an);
12440                         COUNT_BYTES(an_len);
12441                 }
12442         }
12443
12444         /*
12445          * The pipe or mailslot arguments for Transaction start with
12446          * the first setup word (or where the first setup word would
12447          * be if there were any setup words), and run to the current
12448          * offset (which could mean that there aren't any).
12449          */
12450         spo = so;
12451         spc = offset - spo;
12452
12453         /* parameters */
12454         if(po>offset){
12455                 /* We have some initial padding bytes.
12456                 */
12457                 padcnt = po-offset;
12458                 if (padcnt > bc)
12459                         padcnt = bc;
12460                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
12461                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12462                 COUNT_BYTES(padcnt);
12463         }
12464         if(pc){
12465                 CHECK_BYTE_COUNT(pc);
12466                 switch(si->cmd) {
12467
12468                 case SMB_COM_TRANSACTION2:
12469                         /* TRANSACTION2 parameters*/
12470                         offset = dissect_transaction2_request_parameters(tvb,
12471                             pinfo, tree, offset, subcmd, pc);
12472                         bc -= pc;
12473                         break;
12474
12475                 case SMB_COM_TRANSACTION:
12476                         /* TRANSACTION parameters processed below */
12477                         COUNT_BYTES(pc);
12478                         break;
12479                 }
12480         }
12481
12482         /* data */
12483         if(od>offset){
12484                 /* We have some initial padding bytes.
12485                 */
12486                 padcnt = od-offset;
12487                 if (padcnt > bc)
12488                         padcnt = bc;
12489                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
12490                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12491                 COUNT_BYTES(padcnt);
12492         }
12493         if(dc){
12494                 CHECK_BYTE_COUNT(dc);
12495                 switch(si->cmd){
12496
12497                 case SMB_COM_TRANSACTION2:
12498                         /* TRANSACTION2 data*/
12499                         offset = dissect_transaction2_request_data(tvb, pinfo,
12500                             tree, offset, subcmd, dc);
12501                         bc -= dc;
12502                         break;
12503
12504                 case SMB_COM_TRANSACTION:
12505                         /* TRANSACTION data processed below */
12506                         COUNT_BYTES(dc);
12507                         break;
12508                 }
12509         }
12510
12511         /*TRANSACTION request parameters */
12512         if(si->cmd==SMB_COM_TRANSACTION){
12513                 /*XXX replace this block with a function and use that one
12514                      for both requests/responses*/
12515                 if(dd==0){
12516                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12517                         tvbuff_t *sp_tvb, *pd_tvb;
12518
12519                         if(pc>0){
12520                                 if(pc>tvb_length_remaining(tvb, po)){
12521                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12522                                 } else {
12523                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12524                                 }
12525                         } else {
12526                                 p_tvb = NULL;
12527                         }
12528                         if(dc>0){
12529                                 if(dc>tvb_length_remaining(tvb, od)){
12530                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12531                                 } else {
12532                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12533                                 }
12534                         } else {
12535                                 d_tvb = NULL;
12536                         }
12537                         if(sl){
12538                                 if(sl>tvb_length_remaining(tvb, so)){
12539                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12540                                 } else {
12541                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12542                                 }
12543                         } else {
12544                                 s_tvb = NULL;
12545                         }
12546
12547                         if (!si->unidir) {
12548                                 if(!pinfo->fd->flags.visited && si->sip){
12549                                         /*
12550                                          * Allocate a new smb_transact_info_t
12551                                          * structure.
12552                                          */
12553                                         tri = se_alloc(sizeof(smb_transact_info_t));
12554                                         tri->subcmd = -1;
12555                                         tri->trans_subcmd = -1;
12556                                         tri->function = -1;
12557                                         tri->fid = -1;
12558                                         tri->lanman_cmd = 0;
12559                                         tri->param_descrip = NULL;
12560                                         tri->data_descrip = NULL;
12561                                         tri->aux_data_descrip = NULL;
12562                                         tri->info_level = -1;
12563                                         si->sip->extra_info = tri;
12564                                         si->sip->extra_info_type = SMB_EI_TRI;
12565                                 } else {
12566                                         /*
12567                                          * We already filled the structure
12568                                          * in; don't bother doing so again.
12569                                          */
12570                                         tri = NULL;
12571                                 }
12572                         } else {
12573                                 /*
12574                                  * This is a unidirectional message, for
12575                                  * which there will be no reply; don't
12576                                  * bother allocating an "smb_transact_info_t"
12577                                  * structure for it.
12578                                  */
12579                                 tri = NULL;
12580                         }
12581                         dissected_trans = FALSE;
12582                         if (an == NULL)
12583                                 goto endofcommand;
12584                         if(strncmp("\\PIPE\\", an, 6) == 0){
12585                                 if (tri != NULL)
12586                                         tri->subcmd=TRANSACTION_PIPE;
12587
12588                                 /*
12589                                  * A tvbuff containing the setup words and
12590                                  * the pipe path.
12591                                  */
12592                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12593
12594                                 /*
12595                                  * A tvbuff containing the parameters and the
12596                                  * data.
12597                                  */
12598                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12599
12600                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12601                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12602                                     top_tree);
12603
12604                                 /* In case we did not see the TreeConnect call,
12605                                    store this TID here as well as a IPC TID 
12606                                    so we know that future Read/Writes to this 
12607                                    TID is (probably) DCERPC.
12608                                 */
12609                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
12610                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
12611                                 }
12612                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
12613                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12614                                 if (tri != NULL)
12615                                         tri->subcmd=TRANSACTION_MAILSLOT;
12616
12617                                 /*
12618                                  * A tvbuff containing the setup words and
12619                                  * the mailslot path.
12620                                  */
12621                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12622                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12623                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12624                         }
12625                         if (!dissected_trans)
12626                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12627                 } else {
12628                         if(check_col(pinfo->cinfo, COL_INFO)){
12629                                 col_append_str(pinfo->cinfo, COL_INFO,
12630                                         "[transact continuation]");
12631                         }
12632                 }
12633         }
12634
12635         END_OF_SMB
12636
12637         return offset;
12638 }
12639
12640
12641
12642 static int
12643 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12644     int offset, guint16 *bcp, gboolean *trunc)
12645 {
12646         int fn_len;
12647         const char *fn;
12648         int old_offset = offset;
12649         proto_item *item = NULL;
12650         proto_tree *tree = NULL;
12651         smb_info_t *si;
12652         smb_transact2_info_t *t2i;
12653         gboolean resume_keys = FALSE;
12654
12655         si = (smb_info_t *)pinfo->private_data;
12656         DISSECTOR_ASSERT(si);
12657
12658         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
12659                 t2i = si->sip->extra_info;
12660                 if (t2i != NULL)
12661                         resume_keys = t2i->resume_keys;
12662         }
12663
12664         if(parent_tree){
12665                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12666                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12667                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12668                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12669         }
12670
12671         if (resume_keys) {
12672                 /* resume key */
12673                 CHECK_BYTE_COUNT_SUBR(4);
12674                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12675                 COUNT_BYTES_SUBR(4);
12676         }
12677
12678         /* create time */
12679         CHECK_BYTE_COUNT_SUBR(4);
12680         offset = dissect_smb_datetime(tvb, tree, offset,
12681                 hf_smb_create_time,
12682                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12683         *bcp -= 4;
12684
12685         /* access time */
12686         CHECK_BYTE_COUNT_SUBR(4);
12687         offset = dissect_smb_datetime(tvb, tree, offset,
12688                 hf_smb_access_time,
12689                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12690         *bcp -= 4;
12691
12692         /* last write time */
12693         CHECK_BYTE_COUNT_SUBR(4);
12694         offset = dissect_smb_datetime(tvb, tree, offset,
12695                 hf_smb_last_write_time,
12696                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12697         *bcp -= 4;
12698
12699         /* data size */
12700         CHECK_BYTE_COUNT_SUBR(4);
12701         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12702         COUNT_BYTES_SUBR(4);
12703
12704         /* allocation size */
12705         CHECK_BYTE_COUNT_SUBR(4);
12706         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12707         COUNT_BYTES_SUBR(4);
12708
12709         /* File Attributes */
12710         CHECK_BYTE_COUNT_SUBR(2);
12711         offset = dissect_file_attributes(tvb, tree, offset, 2);
12712         *bcp -= 2;
12713
12714         /* file name len */
12715         CHECK_BYTE_COUNT_SUBR(1);
12716         fn_len = tvb_get_guint8(tvb, offset);
12717         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12718         COUNT_BYTES_SUBR(1);
12719         if (si->unicode)
12720                 fn_len += 2;    /* include terminating '\0' */
12721         else
12722                 fn_len++;       /* include terminating '\0' */
12723
12724         /* file name */
12725         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12726         CHECK_STRING_SUBR(fn);
12727         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12728                 fn);
12729         COUNT_BYTES_SUBR(fn_len);
12730
12731         if (check_col(pinfo->cinfo, COL_INFO)) {
12732                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12733                     format_text(fn, strlen(fn)));
12734         }
12735
12736         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
12737         proto_item_set_len(item, offset-old_offset);
12738
12739         *trunc = FALSE;
12740         return offset;
12741 }
12742
12743 static int
12744 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12745     int offset, guint16 *bcp, gboolean *trunc)
12746 {
12747         int fn_len;
12748         const char *fn;
12749         int old_offset = offset;
12750         proto_item *item = NULL;
12751         proto_tree *tree = NULL;
12752         smb_info_t *si;
12753         smb_transact2_info_t *t2i;
12754         gboolean resume_keys = FALSE;
12755
12756         si = (smb_info_t *)pinfo->private_data;
12757         DISSECTOR_ASSERT(si);
12758
12759         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
12760                 t2i = si->sip->extra_info;
12761                 if (t2i != NULL)
12762                         resume_keys = t2i->resume_keys;
12763         }
12764
12765         if(parent_tree){
12766                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12767                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12768                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12769                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12770         }
12771
12772         if (resume_keys) {
12773                 /* resume key */
12774                 CHECK_BYTE_COUNT_SUBR(4);
12775                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12776                 COUNT_BYTES_SUBR(4);
12777         }
12778
12779         /* create time */
12780         CHECK_BYTE_COUNT_SUBR(4);
12781         offset = dissect_smb_datetime(tvb, tree, offset,
12782                 hf_smb_create_time,
12783                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12784         *bcp -= 4;
12785
12786         /* access time */
12787         CHECK_BYTE_COUNT_SUBR(4);
12788         offset = dissect_smb_datetime(tvb, tree, offset,
12789                 hf_smb_access_time,
12790                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12791         *bcp -= 4;
12792
12793         /* last write time */
12794         CHECK_BYTE_COUNT_SUBR(4);
12795         offset = dissect_smb_datetime(tvb, tree, offset,
12796                 hf_smb_last_write_time,
12797                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12798         *bcp -= 4;
12799
12800         /* data size */
12801         CHECK_BYTE_COUNT_SUBR(4);
12802         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12803         COUNT_BYTES_SUBR(4);
12804
12805         /* allocation size */
12806         CHECK_BYTE_COUNT_SUBR(4);
12807         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12808         COUNT_BYTES_SUBR(4);
12809
12810         /* File Attributes */
12811         CHECK_BYTE_COUNT_SUBR(2);
12812         offset = dissect_file_attributes(tvb, tree, offset, 2);
12813         *bcp -= 2;
12814
12815         /* ea length */
12816         CHECK_BYTE_COUNT_SUBR(4);
12817         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12818         COUNT_BYTES_SUBR(4);
12819
12820         /* file name len */
12821         CHECK_BYTE_COUNT_SUBR(1);
12822         fn_len = tvb_get_guint8(tvb, offset);
12823         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12824         COUNT_BYTES_SUBR(1);
12825         if (si->unicode)
12826                 fn_len += 2;    /* include terminating '\0' */
12827         else
12828                 fn_len++;       /* include terminating '\0' */
12829
12830         /* file name */
12831         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12832         CHECK_STRING_SUBR(fn);
12833         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12834                 fn);
12835         COUNT_BYTES_SUBR(fn_len);
12836
12837         if (check_col(pinfo->cinfo, COL_INFO)) {
12838                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12839                     format_text(fn, strlen(fn)));
12840         }
12841
12842         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
12843         proto_item_set_len(item, offset-old_offset);
12844
12845         *trunc = FALSE;
12846         return offset;
12847 }
12848
12849 static int
12850 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12851     int offset, guint16 *bcp, gboolean *trunc)
12852 {
12853         int fn_len;
12854         const char *fn;
12855         int old_offset = offset;
12856         proto_item *item = NULL;
12857         proto_tree *tree = NULL;
12858         smb_info_t *si;
12859         guint32 neo;
12860         int padcnt;
12861
12862         si = (smb_info_t *)pinfo->private_data;
12863         DISSECTOR_ASSERT(si);
12864
12865         if(parent_tree){
12866                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12867                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12868                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12869                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12870         }
12871
12872         /*
12873          * We assume that the presence of a next entry offset implies the
12874          * absence of a resume key, as appears to be the case for 4.3.4.6.
12875          */
12876
12877         /* next entry offset */
12878         CHECK_BYTE_COUNT_SUBR(4);
12879         neo = tvb_get_letohl(tvb, offset);
12880         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12881         COUNT_BYTES_SUBR(4);
12882
12883         /* file index */
12884         CHECK_BYTE_COUNT_SUBR(4);
12885         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12886         COUNT_BYTES_SUBR(4);
12887
12888         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12889         if (*trunc) {
12890           return offset;
12891         }
12892
12893         /* end of file */
12894         CHECK_BYTE_COUNT_SUBR(8);
12895         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12896         COUNT_BYTES_SUBR(8);
12897
12898         /* allocation size */
12899         CHECK_BYTE_COUNT_SUBR(8);
12900         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12901         COUNT_BYTES_SUBR(8);
12902
12903         /* Extended File Attributes */
12904         CHECK_BYTE_COUNT_SUBR(4);
12905         offset = dissect_file_ext_attr(tvb, tree, offset);
12906         *bcp -= 4;
12907
12908         /* file name len */
12909         CHECK_BYTE_COUNT_SUBR(4);
12910         fn_len = tvb_get_letohl(tvb, offset);
12911         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12912         COUNT_BYTES_SUBR(4);
12913
12914         /* file name */
12915         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12916         CHECK_STRING_SUBR(fn);
12917         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12918                 fn);
12919         COUNT_BYTES_SUBR(fn_len);
12920
12921         if (check_col(pinfo->cinfo, COL_INFO)) {
12922                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12923                     format_text(fn, strlen(fn)));
12924         }
12925
12926         /* skip to next structure */
12927         if(neo){
12928                 padcnt = (old_offset + neo) - offset;
12929                 if (padcnt < 0) {
12930                         /*
12931                          * XXX - this is bogus; flag it?
12932                          */
12933                         padcnt = 0;
12934                 }
12935                 if (padcnt != 0) {
12936                         CHECK_BYTE_COUNT_SUBR(padcnt);
12937                         COUNT_BYTES_SUBR(padcnt);
12938                 }
12939         }
12940
12941         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
12942         proto_item_set_len(item, offset-old_offset);
12943
12944         *trunc = FALSE;
12945         return offset;
12946 }
12947
12948 static int
12949 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12950     int offset, guint16 *bcp, gboolean *trunc)
12951 {
12952         int fn_len;
12953         const char *fn;
12954         int old_offset = offset;
12955         proto_item *item = NULL;
12956         proto_tree *tree = NULL;
12957         smb_info_t *si;
12958         guint32 neo;
12959         int padcnt;
12960
12961         si = (smb_info_t *)pinfo->private_data;
12962         DISSECTOR_ASSERT(si);
12963
12964         if(parent_tree){
12965                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12966                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12967                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12968                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12969         }
12970
12971         /*
12972          * We assume that the presence of a next entry offset implies the
12973          * absence of a resume key, as appears to be the case for 4.3.4.6.
12974          */
12975
12976         /* next entry offset */
12977         CHECK_BYTE_COUNT_SUBR(4);
12978         neo = tvb_get_letohl(tvb, offset);
12979         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12980         COUNT_BYTES_SUBR(4);
12981
12982         /* file index */
12983         CHECK_BYTE_COUNT_SUBR(4);
12984         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12985         COUNT_BYTES_SUBR(4);
12986
12987         /* standard 8-byte timestamps */
12988         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12989         if (*trunc) {
12990           return offset;
12991         }
12992
12993         /* end of file */
12994         CHECK_BYTE_COUNT_SUBR(8);
12995         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12996         COUNT_BYTES_SUBR(8);
12997
12998         /* allocation size */
12999         CHECK_BYTE_COUNT_SUBR(8);
13000         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13001         COUNT_BYTES_SUBR(8);
13002
13003         /* Extended File Attributes */
13004         CHECK_BYTE_COUNT_SUBR(4);
13005         offset = dissect_file_ext_attr(tvb, tree, offset);
13006         *bcp -= 4;
13007
13008         /* file name len */
13009         CHECK_BYTE_COUNT_SUBR(4);
13010         fn_len = tvb_get_letohl(tvb, offset);
13011         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13012         COUNT_BYTES_SUBR(4);
13013
13014         /* ea length */
13015         CHECK_BYTE_COUNT_SUBR(4);
13016         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13017         COUNT_BYTES_SUBR(4);
13018
13019         /* file name */
13020         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13021         CHECK_STRING_SUBR(fn);
13022         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13023                 fn);
13024         COUNT_BYTES_SUBR(fn_len);
13025
13026         if (check_col(pinfo->cinfo, COL_INFO)) {
13027                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13028                     format_text(fn, strlen(fn)));
13029         }
13030
13031         /* skip to next structure */
13032         if(neo){
13033                 padcnt = (old_offset + neo) - offset;
13034                 if (padcnt < 0) {
13035                         /*
13036                          * XXX - this is bogus; flag it?
13037                          */
13038                         padcnt = 0;
13039                 }
13040                 if (padcnt != 0) {
13041                         CHECK_BYTE_COUNT_SUBR(padcnt);
13042                         COUNT_BYTES_SUBR(padcnt);
13043                 }
13044         }
13045
13046         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13047         proto_item_set_len(item, offset-old_offset);
13048
13049         *trunc = FALSE;
13050         return offset;
13051 }
13052
13053 static int
13054 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13055     int offset, guint16 *bcp, gboolean *trunc)
13056 {
13057         int fn_len, sfn_len;
13058         const char *fn, *sfn;
13059         int old_offset = offset;
13060         proto_item *item = NULL;
13061         proto_tree *tree = NULL;
13062         smb_info_t *si;
13063         guint32 neo;
13064         int padcnt;
13065
13066         si = (smb_info_t *)pinfo->private_data;
13067         DISSECTOR_ASSERT(si);
13068
13069         if(parent_tree){
13070                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13071                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13072                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13073                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13074         }
13075
13076         /*
13077          * XXX - I have not seen any of these that contain a resume
13078          * key, even though some of the requests had the "return resume
13079          * key" flag set.
13080          */
13081
13082         /* next entry offset */
13083         CHECK_BYTE_COUNT_SUBR(4);
13084         neo = tvb_get_letohl(tvb, offset);
13085         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13086         COUNT_BYTES_SUBR(4);
13087
13088         /* file index */
13089         CHECK_BYTE_COUNT_SUBR(4);
13090         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13091         COUNT_BYTES_SUBR(4);
13092
13093         /* dissect standard 8-byte timestamps */
13094         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13095         if (*trunc) {
13096           return offset;
13097         }
13098
13099         /* end of file */
13100         CHECK_BYTE_COUNT_SUBR(8);
13101         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13102         COUNT_BYTES_SUBR(8);
13103
13104         /* allocation size */
13105         CHECK_BYTE_COUNT_SUBR(8);
13106         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13107         COUNT_BYTES_SUBR(8);
13108
13109         /* Extended File Attributes */
13110         CHECK_BYTE_COUNT_SUBR(4);
13111         offset = dissect_file_ext_attr(tvb, tree, offset);
13112         *bcp -= 4;
13113
13114         /* file name len */
13115         CHECK_BYTE_COUNT_SUBR(4);
13116         fn_len = tvb_get_letohl(tvb, offset);
13117         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13118         COUNT_BYTES_SUBR(4);
13119
13120         /*
13121          * EA length.
13122          *
13123          * XXX - in one captures, this has the topmost bit set, and the
13124          * rest of the bits have the value 7.  Is the topmost bit being
13125          * set some indication that the value *isn't* the length of
13126          * the EAs?
13127          */
13128         CHECK_BYTE_COUNT_SUBR(4);
13129         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13130         COUNT_BYTES_SUBR(4);
13131
13132         /* short file name len */
13133         CHECK_BYTE_COUNT_SUBR(1);
13134         sfn_len = tvb_get_guint8(tvb, offset);
13135         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
13136         COUNT_BYTES_SUBR(1);
13137
13138         /* reserved byte */
13139         CHECK_BYTE_COUNT_SUBR(1);
13140         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13141         COUNT_BYTES_SUBR(1);
13142
13143         /* short file name - it's not always in Unicode */
13144         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
13145         CHECK_STRING_SUBR(sfn);
13146         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
13147                 sfn);
13148         COUNT_BYTES_SUBR(24);
13149
13150         /* file name */
13151         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13152         CHECK_STRING_SUBR(fn);
13153         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13154                 fn);
13155         COUNT_BYTES_SUBR(fn_len);
13156
13157         if (check_col(pinfo->cinfo, COL_INFO)) {
13158                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13159                     format_text(fn, strlen(fn)));
13160         }
13161
13162         /* skip to next structure */
13163         if(neo){
13164                 padcnt = (old_offset + neo) - offset;
13165                 if (padcnt < 0) {
13166                         /*
13167                          * XXX - this is bogus; flag it?
13168                          */
13169                         padcnt = 0;
13170                 }
13171                 if (padcnt != 0) {
13172                         CHECK_BYTE_COUNT_SUBR(padcnt);
13173                         COUNT_BYTES_SUBR(padcnt);
13174                 }
13175         }
13176
13177         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13178         proto_item_set_len(item, offset-old_offset);
13179
13180         *trunc = FALSE;
13181         return offset;
13182 }
13183
13184 static int
13185 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13186     int offset, guint16 *bcp, gboolean *trunc)
13187 {
13188         int fn_len;
13189         const char *fn;
13190         int old_offset = offset;
13191         proto_item *item = NULL;
13192         proto_tree *tree = NULL;
13193         smb_info_t *si;
13194         guint32 neo;
13195         int padcnt;
13196
13197         si = (smb_info_t *)pinfo->private_data;
13198         DISSECTOR_ASSERT(si);
13199
13200         if(parent_tree){
13201                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13202                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13203                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13204                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13205         }
13206
13207         /*
13208          * We assume that the presence of a next entry offset implies the
13209          * absence of a resume key, as appears to be the case for 4.3.4.6.
13210          */
13211
13212         /* next entry offset */
13213         CHECK_BYTE_COUNT_SUBR(4);
13214         neo = tvb_get_letohl(tvb, offset);
13215         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13216         COUNT_BYTES_SUBR(4);
13217
13218         /* file index */
13219         CHECK_BYTE_COUNT_SUBR(4);
13220         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13221         COUNT_BYTES_SUBR(4);
13222
13223         /* file name len */
13224         CHECK_BYTE_COUNT_SUBR(4);
13225         fn_len = tvb_get_letohl(tvb, offset);
13226         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13227         COUNT_BYTES_SUBR(4);
13228
13229         /* file name */
13230         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13231         CHECK_STRING_SUBR(fn);
13232         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13233                 fn);
13234         COUNT_BYTES_SUBR(fn_len);
13235
13236         if (check_col(pinfo->cinfo, COL_INFO)) {
13237                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13238                     format_text(fn, strlen(fn)));
13239         }
13240
13241         /* skip to next structure */
13242         if(neo){
13243                 padcnt = (old_offset + neo) - offset;
13244                 if (padcnt < 0) {
13245                         /*
13246                          * XXX - this is bogus; flag it?
13247                          */
13248                         padcnt = 0;
13249                 }
13250                 if (padcnt != 0) {
13251                         CHECK_BYTE_COUNT_SUBR(padcnt);
13252                         COUNT_BYTES_SUBR(padcnt);
13253                 }
13254         }
13255
13256         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13257         proto_item_set_len(item, offset-old_offset);
13258
13259         *trunc = FALSE;
13260         return offset;
13261 }
13262
13263 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13264
13265 static int
13266 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13267                 proto_tree *tree, int offset, guint16 *bcp,
13268                 gboolean *trunc)
13269 {
13270         smb_info_t *si = pinfo->private_data;
13271         const char *fn;
13272         int fn_len;
13273
13274         DISSECTOR_ASSERT(si);
13275
13276         /* NextEntryOffset */
13277         CHECK_BYTE_COUNT_SUBR(4);
13278         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13279         COUNT_BYTES_SUBR(4);
13280         
13281         /* ResumeKey */
13282         CHECK_BYTE_COUNT_SUBR(4);
13283         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13284         COUNT_BYTES_SUBR(4);
13285
13286         /* End of file (file size) */
13287         CHECK_BYTE_COUNT_SUBR(8);
13288         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13289         COUNT_BYTES_SUBR(8);
13290
13291         /* Number of bytes */
13292         CHECK_BYTE_COUNT_SUBR(8);
13293         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13294         COUNT_BYTES_SUBR(8);
13295
13296         /* Last status change */
13297         CHECK_BYTE_COUNT_SUBR(8);
13298         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13299         *bcp -= 8;
13300
13301         /* Last access time */
13302         CHECK_BYTE_COUNT_SUBR(8);
13303         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13304         *bcp -= 8;
13305
13306         /* Last modification time */
13307         CHECK_BYTE_COUNT_SUBR(8);
13308         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13309         *bcp -= 8;
13310
13311         /* File owner uid */
13312         CHECK_BYTE_COUNT_SUBR(8);
13313         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13314         COUNT_BYTES_SUBR(8);
13315
13316         /* File group gid */
13317         CHECK_BYTE_COUNT_SUBR(8);
13318         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13319         COUNT_BYTES_SUBR(8);
13320
13321         /* File type */
13322         CHECK_BYTE_COUNT_SUBR(4);
13323         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13324         COUNT_BYTES_SUBR(4);
13325
13326         /* Major device number */
13327         CHECK_BYTE_COUNT_SUBR(8);
13328         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13329         COUNT_BYTES_SUBR(8);
13330
13331         /* Minor device number */
13332         CHECK_BYTE_COUNT_SUBR(8);
13333         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13334         COUNT_BYTES_SUBR(8);
13335
13336         /* Unique id */
13337         CHECK_BYTE_COUNT_SUBR(8);
13338         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13339         COUNT_BYTES_SUBR(8);
13340
13341         /* Permissions */
13342         CHECK_BYTE_COUNT_SUBR(8);
13343         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13344         COUNT_BYTES_SUBR(8);
13345
13346         /* Nlinks */
13347         CHECK_BYTE_COUNT_SUBR(8);
13348         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13349         COUNT_BYTES_SUBR(8);
13350
13351         /* Name */
13352
13353         fn = get_unicode_or_ascii_string(
13354                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13355
13356         CHECK_STRING_SUBR(fn);
13357         proto_tree_add_string(
13358                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13359         COUNT_BYTES_SUBR(fn_len);
13360
13361         /* Pad to 4 bytes */
13362
13363         if (offset % 4)
13364                 offset += 4 - (offset % 4);
13365
13366         *trunc = FALSE;
13367         return offset;
13368 }
13369
13370 /*dissect the data block for TRANS2_FIND_FIRST2*/
13371 static int
13372 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13373     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13374 {
13375         smb_info_t *si;
13376
13377         if(!*bcp){
13378                 return offset;
13379         }
13380
13381         si = (smb_info_t *)pinfo->private_data;
13382         DISSECTOR_ASSERT(si);
13383
13384         switch(si->info_level){
13385         case 1:         /*Info Standard*/
13386                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13387                     trunc);
13388                 break;
13389         case 2:         /*Info Query EA Size*/
13390                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13391                     trunc);
13392                 break;
13393         case 3:         /*Info Query EAs From List same as
13394                                 InfoQueryEASize*/
13395                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13396                     trunc);
13397                 break;
13398         case 0x0101:    /*Find File Directory Info*/
13399                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13400                     trunc);
13401                 break;
13402         case 0x0102:    /*Find File Full Directory Info*/
13403                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13404                     trunc);
13405                 break;
13406         case 0x0103:    /*Find File Names Info*/
13407                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13408                     trunc);
13409                 break;
13410         case 0x0104:    /*Find File Both Directory Info*/
13411                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13412                     trunc);
13413                 break;
13414         case 0x0202:    /*Find File UNIX*/
13415                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13416                     trunc);
13417                 break;
13418         default:        /* unknown info level */
13419                 *trunc = FALSE;
13420                 break;
13421         }
13422         return offset;
13423 }
13424
13425
13426 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
13427 static int
13428 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13429 {
13430         guint32 mask;
13431         proto_item *item = NULL;
13432         proto_tree *tree = NULL;
13433
13434         mask = tvb_get_letohl(tvb, offset);
13435
13436         if(parent_tree){
13437                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13438                         "FS Attributes: 0x%08x", mask);
13439                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13440         }
13441
13442         /* case sensitive search */
13443         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13444                 tvb, offset, 4, mask);
13445         /* case preserved names */
13446         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13447                 tvb, offset, 4, mask);
13448         /* unicode on disk */
13449         proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
13450                 tvb, offset, 4, mask);
13451         /* persistent acls */
13452         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13453                 tvb, offset, 4, mask);
13454         /* file compression */
13455         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13456                 tvb, offset, 4, mask);
13457         /* volume quotas */
13458         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13459                 tvb, offset, 4, mask);
13460         /* sparse files */
13461         proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
13462                 tvb, offset, 4, mask);
13463         /* reparse points */
13464         proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
13465                 tvb, offset, 4, mask);
13466         /* remote storage */
13467         proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
13468                 tvb, offset, 4, mask);
13469         /* lfn apis */
13470         proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
13471                 tvb, offset, 4, mask);
13472         /* volume is compressed */
13473         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13474                 tvb, offset, 4, mask);
13475         /* support oids */
13476         proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
13477                 tvb, offset, 4, mask);
13478         /* encryption */
13479         proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
13480                 tvb, offset, 4, mask);
13481         /* named streams */
13482         proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
13483                 tvb, offset, 4, mask);
13484         /* read only volume */
13485         proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
13486                 tvb, offset, 4, mask);
13487
13488
13489         offset += 4;
13490         return offset;
13491 }
13492
13493
13494 static int
13495 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13496 {
13497         guint32 mask;
13498         proto_item *item = NULL;
13499         proto_tree *tree = NULL;
13500
13501         mask = tvb_get_letohl(tvb, offset);
13502
13503         if(parent_tree){
13504                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13505                         "Device Characteristics: 0x%08x", mask);
13506                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13507         }
13508
13509         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13510                 tvb, offset, 4, mask);
13511         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13512                 tvb, offset, 4, mask);
13513         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13514                 tvb, offset, 4, mask);
13515         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13516                 tvb, offset, 4, mask);
13517         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13518                 tvb, offset, 4, mask);
13519         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13520                 tvb, offset, 4, mask);
13521         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13522                 tvb, offset, 4, mask);
13523
13524         offset += 4;
13525         return offset;
13526 }
13527
13528 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13529
13530 static const true_false_string tfs_smb_mac_access_ctrl = {
13531   "Macintosh Access Control Supported",
13532   "Macintosh Access Control Not Supported"
13533 };
13534
13535 static const true_false_string tfs_smb_mac_getset_comments = {
13536   "Macintosh Get & Set Comments Supported",
13537   "Macintosh Get & Set Comments Not Supported"
13538 };
13539
13540 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13541   "Macintosh Get & Set Desktop Database Info Supported",
13542   "Macintosh Get & Set Desktop Database Info Supported"
13543 };
13544
13545 static const true_false_string tfs_smb_mac_unique_ids = {
13546   "Macintosh Unique IDs Supported",
13547   "Macintosh Unique IDs Not Supported"
13548 };
13549
13550 static const true_false_string tfs_smb_mac_streams = {
13551   "Macintosh and Streams Extensions Not Supported",
13552   "Macintosh and Streams Extensions Supported"
13553 };
13554
13555 int
13556 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
13557 {
13558         int fn_len, vll;
13559         const char *fn;
13560
13561         /* create time */
13562         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13563         offset = dissect_nt_64bit_time(tvb, tree, offset,
13564                 hf_smb_create_time);
13565         *bcp -= 8;
13566
13567         /* volume serial number */
13568         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13569         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13570         COUNT_BYTES_TRANS_SUBR(4);
13571
13572         /* volume label length */
13573         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13574         vll = tvb_get_letohl(tvb, offset);
13575         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13576         COUNT_BYTES_TRANS_SUBR(4);
13577
13578         /* 2 reserved bytes */
13579         CHECK_BYTE_COUNT_TRANS_SUBR(2);
13580         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13581         COUNT_BYTES_TRANS_SUBR(2);
13582
13583         /* label */
13584         fn_len = vll;
13585         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
13586         CHECK_STRING_TRANS_SUBR(fn);
13587         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13588                 fn);
13589         COUNT_BYTES_TRANS_SUBR(fn_len);
13590
13591         return offset;
13592 }
13593
13594 int
13595 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13596 {
13597         /* allocation size */
13598         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13599         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13600         COUNT_BYTES_TRANS_SUBR(8);
13601
13602         /* free allocation units */
13603         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13604         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13605         COUNT_BYTES_TRANS_SUBR(8);
13606
13607         /* sectors per unit */
13608         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13609         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13610         COUNT_BYTES_TRANS_SUBR(4);
13611
13612         /* bytes per sector */
13613         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13614         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13615         COUNT_BYTES_TRANS_SUBR(4);
13616
13617         return offset;
13618 }
13619
13620 int
13621 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13622 {
13623         /* device type */
13624         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13625         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13626         COUNT_BYTES_TRANS_SUBR(4);
13627
13628         /* device characteristics */
13629         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13630         offset = dissect_device_characteristics(tvb, tree, offset);
13631         *bcp -= 4;
13632
13633         return offset;
13634 }
13635
13636 int
13637 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
13638 {
13639         int fn_len, fnl;
13640         const char *fn;
13641
13642         /* FS attributes */
13643         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13644         offset = dissect_fs_attributes(tvb, tree, offset);
13645         *bcp -= 4;
13646
13647         /* max name len */
13648         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13649         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13650         COUNT_BYTES_TRANS_SUBR(4);
13651
13652         /* fs name length */
13653         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13654         fnl = tvb_get_letohl(tvb, offset);
13655         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13656         COUNT_BYTES_TRANS_SUBR(4);
13657
13658         /* label */
13659         fn_len = fnl;
13660         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
13661         CHECK_STRING_TRANS_SUBR(fn);
13662         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13663                 fn);
13664         COUNT_BYTES_TRANS_SUBR(fn_len);
13665
13666         return offset;
13667 }
13668
13669 int
13670 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
13671 {
13672         CHECK_BYTE_COUNT_TRANS_SUBR(64);
13673
13674         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
13675
13676         COUNT_BYTES_TRANS_SUBR(64);
13677
13678         return offset;
13679 }
13680
13681 int
13682 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
13683 {
13684         /* allocation size */
13685         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13686         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13687         COUNT_BYTES_TRANS_SUBR(8);
13688
13689         /* caller free allocation units */
13690         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13691         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13692         COUNT_BYTES_TRANS_SUBR(8);
13693
13694         /* actual free allocation units */
13695         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13696         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13697         COUNT_BYTES_TRANS_SUBR(8);
13698
13699         /* sectors per unit */
13700         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13701         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13702         COUNT_BYTES_TRANS_SUBR(4);
13703
13704         /* bytes per sector */
13705         CHECK_BYTE_COUNT_TRANS_SUBR(4);
13706         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13707         COUNT_BYTES_TRANS_SUBR(4);
13708
13709         return offset;
13710 }
13711
13712 static int
13713 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13714     int offset, guint16 *bcp)
13715 {
13716         smb_info_t *si;
13717         int fn_len, vll;
13718         const char *fn;
13719         guint support = 0;
13720         proto_item *item = NULL;
13721         proto_tree *ti = NULL;
13722
13723         if(!*bcp){
13724                 return offset;
13725         }
13726
13727         si = (smb_info_t *)pinfo->private_data;
13728         DISSECTOR_ASSERT(si);
13729
13730         switch(si->info_level){
13731         case 1:         /* SMB_INFO_ALLOCATION */
13732                 /* filesystem id */
13733                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13734                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13735                 COUNT_BYTES_TRANS_SUBR(4);
13736
13737                 /* sectors per unit */
13738                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13739                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13740                 COUNT_BYTES_TRANS_SUBR(4);
13741
13742                 /* units */
13743                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13744                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13745                 COUNT_BYTES_TRANS_SUBR(4);
13746
13747                 /* avail units */
13748                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13749                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13750                 COUNT_BYTES_TRANS_SUBR(4);
13751
13752                 /* bytes per sector, only 16bit integer here */
13753                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13754                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13755                 COUNT_BYTES_TRANS_SUBR(2);
13756
13757                 break;
13758         case 2:         /* SMB_INFO_VOLUME */
13759                 /* volume serial number */
13760                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13761                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13762                 COUNT_BYTES_TRANS_SUBR(4);
13763
13764                 /* volume label length, only one byte here */
13765                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13766                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13767                 COUNT_BYTES_TRANS_SUBR(1);
13768
13769                 /* label */
13770                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13771                 CHECK_STRING_TRANS_SUBR(fn);
13772                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13773                         fn);
13774                 COUNT_BYTES_TRANS_SUBR(fn_len);
13775
13776                 break;
13777         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13778         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13779                 /* volume label length */
13780                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13781                 vll = tvb_get_letohl(tvb, offset);
13782                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13783                 COUNT_BYTES_TRANS_SUBR(4);
13784
13785                 /* label */
13786                 fn_len = vll;
13787                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13788                 CHECK_STRING_TRANS_SUBR(fn);
13789                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13790                         fn);
13791                 COUNT_BYTES_TRANS_SUBR(fn_len);
13792
13793                 break;
13794         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13795         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13796                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
13797                 break;
13798         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13799         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13800                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
13801                 break;
13802         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13803         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13804                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
13805                 break;
13806         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13807         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13808                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
13809                 break;
13810         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13811                 proto_item *item = NULL;
13812                 proto_tree *subtree = NULL;
13813                 guint32 caps_lo, caps_hi;
13814
13815                 /* MajorVersionNumber */
13816                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13817                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13818                 COUNT_BYTES_TRANS_SUBR(2);
13819
13820                 /* MinorVersionNumber */
13821                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13822                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13823                 COUNT_BYTES_TRANS_SUBR(2);
13824
13825                 /* Capability */
13826
13827                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13828
13829                 caps_lo = tvb_get_letohl(tvb, offset);
13830                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13831
13832                 if (tree) {
13833                         item = proto_tree_add_text(
13834                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13835                                 caps_hi, caps_lo);
13836                         subtree = proto_item_add_subtree(
13837                                 item, ett_smb_unix_capabilities);
13838                 }
13839
13840                 proto_tree_add_boolean(
13841                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13842                         caps_lo);
13843
13844                 proto_tree_add_boolean(
13845                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13846                         caps_lo);
13847
13848                 COUNT_BYTES_TRANS_SUBR(8);
13849
13850                 break;
13851         }
13852         case 0x301:     /* MAC_QUERY_FS_INFO */
13853                 /* Create time */
13854                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13855                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
13856                 *bcp -= 8;
13857                 /* Modify Time */
13858                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13859                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13860                 *bcp -= 8;
13861                 /* Backup Time */
13862                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13863                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13864                 *bcp -= 8;
13865                 /* Allocation blocks */
13866                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13867                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13868                                     offset,
13869                                     4, TRUE);
13870                 COUNT_BYTES_TRANS_SUBR(4);
13871                 /* Allocation Block Size */
13872                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13873                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13874                                     offset, 4, TRUE);
13875                 COUNT_BYTES_TRANS_SUBR(4);
13876                 /* Free Block Count */
13877                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13878                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13879                                     offset, 4, TRUE);
13880                 COUNT_BYTES_TRANS_SUBR(4);
13881                 /* Finder Info ... */
13882                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13883                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13884                                             offset, 32,
13885                                             tvb_get_ptr(tvb, offset,32),
13886                                             "Finder Info: %s",
13887                                             tvb_format_text(tvb, offset, 32));
13888                 COUNT_BYTES_TRANS_SUBR(32);
13889                 /* Number Files */
13890                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13891                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13892                                     offset, 4, TRUE);
13893                 COUNT_BYTES_TRANS_SUBR(4);
13894                 /* Number of Root Directories */
13895                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13896                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13897                                     offset, 4, TRUE);
13898                 COUNT_BYTES_TRANS_SUBR(4);
13899                 /* Number of files */
13900                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13901                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13902                                     offset, 4, TRUE);
13903                 COUNT_BYTES_TRANS_SUBR(4);
13904                 /* Dir Count */
13905                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13906                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13907                                     offset, 4, TRUE);
13908                 COUNT_BYTES_TRANS_SUBR(4);
13909                 /* Mac Support Flags */
13910                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13911                 support = tvb_get_ntohl(tvb, offset);
13912                 item = proto_tree_add_text(tree, tvb, offset, 4,
13913                                            "Mac Support Flags: 0x%08x", support);
13914                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13915                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13916                                        tvb, offset, 4, support);
13917                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13918                                        tvb, offset, 4, support);
13919                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13920                                        tvb, offset, 4, support);
13921                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13922                                        tvb, offset, 4, support);
13923                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13924                                        tvb, offset, 4, support);
13925                 COUNT_BYTES_TRANS_SUBR(4);
13926                 break;
13927         case 1006:      /* QUERY_FS_QUOTA_INFO */
13928                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13929                 break;
13930         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13931                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
13932                 break;
13933         case 1008: /* Query Object ID */ {
13934                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
13935                 break;
13936             }
13937         }
13938
13939         return offset;
13940 }
13941
13942 static int
13943 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13944     proto_tree *parent_tree)
13945 {
13946         proto_item *item = NULL;
13947         proto_tree *tree = NULL;
13948         smb_info_t *si;
13949         smb_transact2_info_t *t2i;
13950         int count;
13951         gboolean trunc;
13952         int offset = 0;
13953         guint16 dc;
13954
13955         dc = tvb_reported_length(tvb);
13956
13957         si = (smb_info_t *)pinfo->private_data;
13958         DISSECTOR_ASSERT(si);
13959
13960         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
13961                 t2i = si->sip->extra_info;
13962         else
13963                 t2i = NULL;
13964
13965         if(parent_tree){
13966                 if (t2i != NULL && t2i->subcmd != -1) {
13967                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13968                                 "%s Data",
13969                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13970                                         "Unknown (0x%02x)"));
13971                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13972                 } else {
13973                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13974                                 "Unknown Transaction2 Data");
13975                 }
13976         }
13977
13978         if (t2i == NULL) {
13979                 offset += dc;
13980                 return offset;
13981         }
13982         switch(t2i->subcmd){
13983         case 0x00:      /*TRANS2_OPEN2*/
13984                 /* XXX not implemented yet. See SNIA doc */
13985                 break;
13986         case 0x01:      /*TRANS2_FIND_FIRST2*/
13987                 /* returned data */
13988                 count = si->info_count;
13989
13990         if(count == -1) {
13991             break;
13992         }
13993                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13994                         col_append_fstr(pinfo->cinfo, COL_INFO,
13995                         ", Files:");
13996                 }
13997
13998                 while(count--){
13999                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14000                                 offset, &dc, &trunc);
14001                         if (trunc)
14002                                 break;
14003                 }
14004                 break;
14005         case 0x02:      /*TRANS2_FIND_NEXT2*/
14006                 /* returned data */
14007                 count = si->info_count;
14008
14009         if(count == -1) {
14010             break;
14011         }
14012                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14013                         col_append_fstr(pinfo->cinfo, COL_INFO,
14014                         ", Files:");
14015                 }
14016
14017                 while(count--){
14018                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14019                                 offset, &dc, &trunc);
14020                         if (trunc)
14021                                 break;
14022                 }
14023                 break;
14024         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14025                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
14026                 break;
14027         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14028                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14029                 break;
14030         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14031                 /* no data in this response */
14032                 break;
14033         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14034                 /* identical to QUERY_PATH_INFO */
14035                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14036                 break;
14037         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14038                 /* no data in this response */
14039                 break;
14040         case 0x09:      /*TRANS2_FSCTL*/
14041                 /* XXX dont know how to dissect this one (yet)*/
14042
14043                 /*
14044                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14045                  * Extensions Version 3.0, Document Version 1.11,
14046                  * July 19, 1990" says this this contains a
14047                  * "File system specific return data block".
14048                  * (That means we may not be able to dissect it in any
14049                  * case.)
14050                  */
14051                 break;
14052         case 0x0a:      /*TRANS2_IOCTL2*/
14053                 /* XXX dont know how to dissect this one (yet)*/
14054
14055                 /*
14056                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14057                  * Extensions Version 3.0, Document Version 1.11,
14058                  * July 19, 1990" says this this contains a
14059                  * "Device/function specific return data block".
14060                  * (That means we may not be able to dissect it in any
14061                  * case.)
14062                  */
14063                 break;
14064         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14065                 /* XXX dont know how to dissect this one (yet)*/
14066
14067                 /*
14068                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14069                  * Extensions Version 3.0, Document Version 1.11,
14070                  * July 19, 1990" says this this contains "the level
14071                  * dependent information about the changes which
14072                  * occurred".
14073                  */
14074                 break;
14075         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14076                 /* XXX dont know how to dissect this one (yet)*/
14077
14078                 /*
14079                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14080                  * Extensions Version 3.0, Document Version 1.11,
14081                  * July 19, 1990" says this this contains "the level
14082                  * dependent information about the changes which
14083                  * occurred".
14084                  */
14085                 break;
14086         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14087                 /* no data in this response */
14088                 break;
14089         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14090                 /* XXX dont know how to dissect this one (yet)*/
14091                 break;
14092         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14093                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
14094                 break;
14095         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14096                 /* the SNIA spec appears to say the response has no data */
14097                 break;
14098         case -1:
14099                 /*
14100                  * We don't know what the matching request was; don't
14101                  * bother putting anything else into the tree for the data.
14102                  */
14103                 offset += dc;
14104                 dc = 0;
14105                 break;
14106         }
14107
14108         /* ooops there were data we didnt know how to process */
14109         if(dc != 0){
14110                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
14111                 offset += dc;
14112         }
14113
14114         return offset;
14115 }
14116
14117
14118 static void
14119 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14120 {
14121         proto_item *item = NULL;
14122         proto_tree *tree = NULL;
14123         smb_info_t *si;
14124         smb_transact2_info_t *t2i;
14125         guint16 fid;
14126         int lno;
14127         int offset = 0;
14128         int pc;
14129
14130         pc = tvb_reported_length(tvb);
14131
14132         si = (smb_info_t *)pinfo->private_data;
14133         DISSECTOR_ASSERT(si);
14134
14135         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14136                 t2i = si->sip->extra_info;
14137         else
14138                 t2i = NULL;
14139
14140         if(parent_tree){
14141                 if (t2i != NULL && t2i->subcmd != -1) {
14142                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14143                                 "%s Parameters",
14144                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14145                                                 "Unknown (0x%02x)"));
14146                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
14147                 } else {
14148                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14149                                 "Unknown Transaction2 Parameters");
14150                 }
14151         }
14152
14153         if (t2i == NULL) {
14154                 offset += pc;
14155                 return;
14156         }
14157         switch(t2i->subcmd){
14158         case 0x00:      /*TRANS2_OPEN2*/
14159                 /* fid */
14160                 fid = tvb_get_letohs(tvb, offset);
14161                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
14162                 offset += 2;
14163
14164                 /*
14165                  * XXX - Microsoft Networks SMB File Sharing Protocol
14166                  * Extensions Version 3.0, Document Version 1.11,
14167                  * July 19, 1990 says that the file attributes, create
14168                  * time (which it says is the last modification time),
14169                  * data size, granted access, file type, and IPC state
14170                  * are returned only if bit 0 is set in the open flags,
14171                  * and that the EA length is returned only if bit 3
14172                  * is set in the open flags.  Does that mean that,
14173                  * at least in that SMB dialect, those fields are not
14174                  * present in the reply parameters if the bits in
14175                  * question aren't set?
14176                  */
14177
14178                 /* File Attributes */
14179                 offset = dissect_file_attributes(tvb, tree, offset, 2);
14180
14181                 /* create time */
14182                 offset = dissect_smb_datetime(tvb, tree, offset,
14183                         hf_smb_create_time,
14184                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
14185
14186                 /* data size */
14187                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
14188                 offset += 4;
14189
14190                 /* granted access */
14191                 offset = dissect_access(tvb, tree, offset, "Granted");
14192
14193                 /* File Type */
14194                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
14195                 offset += 2;
14196
14197                 /* IPC State */
14198                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
14199
14200                 /* open_action */
14201                 offset = dissect_open_action(tvb, tree, offset);
14202
14203                 /* server unique file ID */
14204                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
14205                 offset += 4;
14206
14207                 /* ea error offset, only a 16 bit integer here */
14208                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14209                 offset += 2;
14210
14211                 /* ea length */
14212                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
14213                 offset += 4;
14214
14215                 break;
14216         case 0x01:      /*TRANS2_FIND_FIRST2*/
14217                 /* Find First2 information level */
14218                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
14219
14220                 /* sid */
14221                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
14222                 offset += 2;
14223
14224                 /* search count */
14225                 si->info_count = tvb_get_letohs(tvb, offset);
14226                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14227                 offset += 2;
14228
14229                 /* end of search */
14230                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14231                 offset += 2;
14232
14233                 /* ea error offset, only a 16 bit integer here */
14234                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14235                 offset += 2;
14236
14237                 /* last name offset */
14238                 lno = tvb_get_letohs(tvb, offset);
14239                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14240                 offset += 2;
14241
14242                 break;
14243         case 0x02:      /*TRANS2_FIND_NEXT2*/
14244                 /* search count */
14245                 si->info_count = tvb_get_letohs(tvb, offset);
14246                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14247                 offset += 2;
14248
14249                 /* end of search */
14250                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14251                 offset += 2;
14252
14253                 /* ea_error_offset, only a 16 bit integer here*/
14254                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14255                 offset += 2;
14256
14257                 /* last name offset */
14258                 lno = tvb_get_letohs(tvb, offset);
14259                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14260                 offset += 2;
14261
14262                 break;
14263         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14264                 /* no parameter block here */
14265                 break;
14266         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14267                 /* ea_error_offset, only a 16 bit integer here*/
14268                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14269                 offset += 2;
14270
14271                 break;
14272         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14273                 /* ea_error_offset, only a 16 bit integer here*/
14274                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14275                 offset += 2;
14276
14277                 break;
14278         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14279                 /* ea_error_offset, only a 16 bit integer here*/
14280                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14281                 offset += 2;
14282
14283                 break;
14284         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14285                 /* ea_error_offset, only a 16 bit integer here*/
14286                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14287                 offset += 2;
14288
14289                 break;
14290         case 0x09:      /*TRANS2_FSCTL*/
14291                 /* XXX dont know how to dissect this one (yet)*/
14292
14293                 /*
14294                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14295                  * Extensions Version 3.0, Document Version 1.11,
14296                  * July 19, 1990" says this this contains a
14297                  * "File system specific return parameter block".
14298                  * (That means we may not be able to dissect it in any
14299                  * case.)
14300                  */
14301                 break;
14302         case 0x0a:      /*TRANS2_IOCTL2*/
14303                 /* XXX dont know how to dissect this one (yet)*/
14304
14305                 /*
14306                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14307                  * Extensions Version 3.0, Document Version 1.11,
14308                  * July 19, 1990" says this this contains a
14309                  * "Device/function specific return parameter block".
14310                  * (That means we may not be able to dissect it in any
14311                  * case.)
14312                  */
14313                 break;
14314         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14315                 /* Find Notify information level */
14316                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14317
14318                 /* Monitor handle */
14319                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14320                 offset += 2;
14321
14322                 /* Change count */
14323                 si->info_count = tvb_get_letohs(tvb, offset);
14324                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14325                 offset += 2;
14326
14327                 /* ea_error_offset, only a 16 bit integer here*/
14328                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14329                 offset += 2;
14330
14331                 break;
14332         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14333                 /* Find Notify information level */
14334                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14335
14336                 /* Change count */
14337                 si->info_count = tvb_get_letohs(tvb, offset);
14338                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14339                 offset += 2;
14340
14341                 /* ea_error_offset, only a 16 bit integer here*/
14342                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14343                 offset += 2;
14344
14345                 break;
14346         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14347                 /* ea error offset, only a 16 bit integer here */
14348                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14349                 offset += 2;
14350
14351                 break;
14352         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14353                 /* XXX dont know how to dissect this one (yet)*/
14354                 break;
14355         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14356                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14357                 break;
14358         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14359                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14360                 break;
14361         case -1:
14362                 /*
14363                  * We don't know what the matching request was; don't
14364                  * bother putting anything else into the tree for the data.
14365                  */
14366                 offset += pc;
14367                 break;
14368         }
14369
14370         /* ooops there were data we didnt know how to process */
14371         if(offset<pc){
14372                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14373                 offset += pc-offset;
14374         }
14375 }
14376
14377
14378 static int
14379 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14380 {
14381         guint8 sc, wc;
14382         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14383         smb_info_t *si;
14384         smb_transact2_info_t *t2i = NULL;
14385         guint16 bc;
14386         int padcnt;
14387         gboolean dissected_trans;
14388         fragment_data *r_fd = NULL;
14389         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14390         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14391         gboolean save_fragmented;
14392
14393         si = (smb_info_t *)pinfo->private_data;
14394         DISSECTOR_ASSERT(si);
14395
14396         switch(si->cmd){
14397         case SMB_COM_TRANSACTION2:
14398                 /* transaction2 */
14399                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
14400                         t2i = si->sip->extra_info;
14401                 } else
14402                         t2i = NULL;
14403                 if (t2i == NULL) {
14404                         /*
14405                          * We didn't see the matching request, so we don't
14406                          * know what type of transaction this is.
14407                          */
14408                         proto_tree_add_text(tree, tvb, 0, 0,
14409                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14410                         if (check_col(pinfo->cinfo, COL_INFO)) {
14411                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14412                         }
14413                 } else {
14414                         si->info_level = t2i->info_level;
14415                         if (t2i->subcmd == -1) {
14416                                 /*
14417                                  * We didn't manage to extract the subcommand
14418                                  * from the matching request (perhaps because
14419                                  * the frame was short), so we don't know what
14420                                  * type of transaction this is.
14421                                  */
14422                                 proto_tree_add_text(tree, tvb, 0, 0,
14423                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14424                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14425                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14426                                 }
14427                         } else {
14428                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14429                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14430                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14431                                                 val_to_str(t2i->subcmd,
14432                                                         trans2_cmd_vals,
14433                                                         "<unknown (0x%02x)>"));
14434                                 }
14435                         }
14436                 }
14437                 break;
14438         }
14439
14440         WORD_COUNT;
14441
14442         /* total param count, only a 16bit integer here */
14443         tp = tvb_get_letohs(tvb, offset);
14444         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14445         offset += 2;
14446
14447         /* total data count, only a 16 bit integer here */
14448         td = tvb_get_letohs(tvb, offset);
14449         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14450         offset += 2;
14451
14452         /* 2 reserved bytes */
14453         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14454         offset += 2;
14455
14456         /* param count */
14457         pc = tvb_get_letohs(tvb, offset);
14458         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14459         offset += 2;
14460
14461         /* param offset */
14462         po = tvb_get_letohs(tvb, offset);
14463         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14464         offset += 2;
14465
14466         /* param disp */
14467         pd = tvb_get_letohs(tvb, offset);
14468         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14469         offset += 2;
14470
14471         /* data count */
14472         dc = tvb_get_letohs(tvb, offset);
14473         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14474         offset += 2;
14475
14476         /* data offset */
14477         od = tvb_get_letohs(tvb, offset);
14478         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14479         offset += 2;
14480
14481         /* data disp */
14482         dd = tvb_get_letohs(tvb, offset);
14483         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14484         offset += 2;
14485
14486         /* setup count */
14487         sc = tvb_get_guint8(tvb, offset);
14488         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14489         offset += 1;
14490
14491         /* reserved byte */
14492         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14493         offset += 1;
14494
14495
14496         /* if there were any setup bytes, put them in a tvb for later */
14497         if(sc){
14498                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14499                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14500                 } else {
14501                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14502                 }
14503                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14504         } else {
14505                 s_tvb = NULL;
14506                 sp_tvb=NULL;
14507         }
14508         offset += 2*sc;
14509
14510
14511         BYTE_COUNT;
14512
14513
14514         /* reassembly of SMB Transaction data payload.
14515            In this section we do reassembly of both the data and parameters
14516            blocks of the SMB transaction command.
14517         */
14518         save_fragmented = pinfo->fragmented;
14519         /* do we need reassembly? */
14520         if( (td!=dc) || (tp!=pc) ){
14521                 /* oh yeah, either data or parameter section needs
14522                    reassembly
14523                 */
14524                 pinfo->fragmented = TRUE;
14525                 if(smb_trans_reassembly){
14526                         /* ...and we were told to do reassembly */
14527                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14528                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14529                                                              po, pc, pd, td+tp);
14530
14531                         }
14532                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14533                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14534                                                              od, dc, dd+tp, td+tp);
14535                         }
14536                 }
14537         }
14538
14539         /* if we got a reassembled fd structure from the reassembly routine we must
14540            create pd_tvb from it
14541         */
14542         if(r_fd){
14543         proto_item *frag_tree_item;
14544
14545                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14546                                              r_fd->datalen);
14547                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14548                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14549                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
14550         }
14551
14552
14553         if(pd_tvb){
14554                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14555                 if(tp){
14556                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14557                 }
14558                 if(td){
14559                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14560                 }
14561         } else {
14562                 /* It was not reassembled. Do as best as we can.
14563                  * in this case we always try to dissect the stuff if
14564                  * data and param displacement is 0. i.e. for the first
14565                  * (and maybe only) packet.
14566                  */
14567                 if( (pd==0) && (dd==0) ){
14568                         int min;
14569                         int reported_min;
14570                         min = MIN(pc,tvb_length_remaining(tvb,po));
14571                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14572                         if(min && reported_min) {
14573                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14574                         }
14575                         min = MIN(dc,tvb_length_remaining(tvb,od));
14576                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14577                         if(min && reported_min) {
14578                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14579                         }
14580                         /*
14581                          * A tvbuff containing the parameters
14582                          * and the data.
14583                          * XXX - check pc and dc as well?
14584                          */
14585                         if (tvb_length_remaining(tvb, po)){
14586                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14587                         }
14588                 }
14589         }
14590
14591
14592
14593         /* parameters */
14594         if(po>offset){
14595                 /* We have some padding bytes.
14596                 */
14597                 padcnt = po-offset;
14598                 if (padcnt > bc)
14599                         padcnt = bc;
14600                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14601                 COUNT_BYTES(padcnt);
14602         }
14603         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14604                 /* TRANSACTION2 parameters*/
14605                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14606         }
14607         COUNT_BYTES(pc);
14608
14609
14610         /* data */
14611         if(od>offset){
14612                 /* We have some initial padding bytes.
14613                 */
14614                 padcnt = od-offset;
14615                 if (padcnt > bc)
14616                         padcnt = bc;
14617                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14618                 COUNT_BYTES(padcnt);
14619         }
14620         /*
14621          * If the data count is bigger than the count of bytes
14622          * remaining, clamp it so that the count of bytes remaining
14623          * doesn't go negative.
14624          */
14625         if (dc > bc)
14626                 dc = bc;
14627         COUNT_BYTES(dc);
14628
14629
14630
14631         /* from now on, everything is in separate tvbuffs so we dont count
14632            the bytes with COUNT_BYTES any more.
14633            neither do we reference offset any more (which by now points to the
14634            first byte AFTER this PDU */
14635
14636
14637         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14638                 /* TRANSACTION2 parameters*/
14639                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14640         }
14641
14642
14643         if(si->cmd==SMB_COM_TRANSACTION){
14644                 smb_transact_info_t *tri;
14645
14646                 dissected_trans = FALSE;
14647                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_TRI)
14648                         tri = si->sip->extra_info;
14649                 else
14650                         tri = NULL;
14651                 if (tri != NULL) {
14652                         switch(tri->subcmd){
14653
14654                         case TRANSACTION_PIPE:
14655                                 /* This function is safe to call for
14656                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14657                                    know them at this point.
14658                                    It's also safe to call if "p_tvb"
14659                                    or "d_tvb" are null.
14660                                 */
14661                                 if( pd_tvb) {
14662                                         dissected_trans = dissect_pipe_smb(
14663                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14664                                                 d_tvb, NULL, pinfo, top_tree);
14665                                 }
14666                                 break;
14667
14668                         case TRANSACTION_MAILSLOT:
14669                                 /* This one should be safe to call
14670                                    even if s_tvb and sp_tvb is NULL
14671                                 */
14672                                 if(d_tvb){
14673                                         dissected_trans = dissect_mailslot_smb(
14674                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14675                                                 top_tree);
14676                                 }
14677                                 break;
14678                         }
14679                 }
14680                 if (!dissected_trans) {
14681                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14682                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14683                 }
14684         }
14685
14686
14687         if( (p_tvb==0) && (d_tvb==0) ){
14688                 if(check_col(pinfo->cinfo, COL_INFO)){
14689                         col_append_str(pinfo->cinfo, COL_INFO,
14690                                        "[transact continuation]");
14691                 }
14692         }
14693
14694         pinfo->fragmented = save_fragmented;
14695         END_OF_SMB
14696
14697         return offset;
14698 }
14699
14700
14701 static int
14702 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14703 {
14704         guint8 wc;
14705         guint16 bc;
14706
14707         WORD_COUNT;
14708
14709         /* Monitor handle */
14710         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14711         offset += 2;
14712
14713         BYTE_COUNT;
14714
14715         END_OF_SMB
14716
14717         return offset;
14718 }
14719
14720 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14721    END Transaction/Transaction2 Primary and secondary requests
14722    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14723
14724
14725 static int
14726 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14727 {
14728         guint8 wc;
14729         guint16 bc;
14730
14731         WORD_COUNT;
14732
14733         if (wc != 0) {
14734                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
14735                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14736                 offset += wc*2;
14737         }
14738
14739         BYTE_COUNT;
14740
14741         if (bc != 0) {
14742                 tvb_ensure_bytes_exist(tvb, offset, bc);
14743                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14744                 offset += bc;
14745                 bc = 0;
14746         }
14747
14748         END_OF_SMB
14749
14750         return offset;
14751 }
14752
14753 typedef struct _smb_function {
14754        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14755        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14756 } smb_function;
14757
14758 static smb_function smb_dissector[256] = {
14759   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14760   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14761   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14762   /* 0x03 Create File*/  {dissect_create_file_request, dissect_create_file_response},
14763   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14764   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
14765   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14766   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14767   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14768   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14769   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14770   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14771   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14772   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14773   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14774   /* 0x0f Create New*/  {dissect_create_file_request, dissect_create_new_response},
14775
14776   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14777   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14778   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14779   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14780   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14781   /* 0x15 */  {dissect_unknown, dissect_unknown},
14782   /* 0x16 */  {dissect_unknown, dissect_unknown},
14783   /* 0x17 */  {dissect_unknown, dissect_unknown},
14784   /* 0x18 */  {dissect_unknown, dissect_unknown},
14785   /* 0x19 */  {dissect_unknown, dissect_unknown},
14786   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14787   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14788   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14789   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14790   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14791   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14792
14793   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14794   /* 0x21 */  {dissect_unknown, dissect_unknown},
14795   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14796   /* 0x23 Query Info2*/  {dissect_query_information2_request, dissect_query_information2_response},
14797   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14798   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14799   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14800   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14801   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14802   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14803   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14804   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14805   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14806   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14807   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14808   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14809
14810   /* 0x30 */  {dissect_unknown, dissect_unknown},
14811   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14812   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14813   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14814   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14815   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14816   /* 0x36 */  {dissect_unknown, dissect_unknown},
14817   /* 0x37 */  {dissect_unknown, dissect_unknown},
14818   /* 0x38 */  {dissect_unknown, dissect_unknown},
14819   /* 0x39 */  {dissect_unknown, dissect_unknown},
14820   /* 0x3a */  {dissect_unknown, dissect_unknown},
14821   /* 0x3b */  {dissect_unknown, dissect_unknown},
14822   /* 0x3c */  {dissect_unknown, dissect_unknown},
14823   /* 0x3d */  {dissect_unknown, dissect_unknown},
14824   /* 0x3e */  {dissect_unknown, dissect_unknown},
14825   /* 0x3f */  {dissect_unknown, dissect_unknown},
14826
14827   /* 0x40 */  {dissect_unknown, dissect_unknown},
14828   /* 0x41 */  {dissect_unknown, dissect_unknown},
14829   /* 0x42 */  {dissect_unknown, dissect_unknown},
14830   /* 0x43 */  {dissect_unknown, dissect_unknown},
14831   /* 0x44 */  {dissect_unknown, dissect_unknown},
14832   /* 0x45 */  {dissect_unknown, dissect_unknown},
14833   /* 0x46 */  {dissect_unknown, dissect_unknown},
14834   /* 0x47 */  {dissect_unknown, dissect_unknown},
14835   /* 0x48 */  {dissect_unknown, dissect_unknown},
14836   /* 0x49 */  {dissect_unknown, dissect_unknown},
14837   /* 0x4a */  {dissect_unknown, dissect_unknown},
14838   /* 0x4b */  {dissect_unknown, dissect_unknown},
14839   /* 0x4c */  {dissect_unknown, dissect_unknown},
14840   /* 0x4d */  {dissect_unknown, dissect_unknown},
14841   /* 0x4e */  {dissect_unknown, dissect_unknown},
14842   /* 0x4f */  {dissect_unknown, dissect_unknown},
14843
14844   /* 0x50 */  {dissect_unknown, dissect_unknown},
14845   /* 0x51 */  {dissect_unknown, dissect_unknown},
14846   /* 0x52 */  {dissect_unknown, dissect_unknown},
14847   /* 0x53 */  {dissect_unknown, dissect_unknown},
14848   /* 0x54 */  {dissect_unknown, dissect_unknown},
14849   /* 0x55 */  {dissect_unknown, dissect_unknown},
14850   /* 0x56 */  {dissect_unknown, dissect_unknown},
14851   /* 0x57 */  {dissect_unknown, dissect_unknown},
14852   /* 0x58 */  {dissect_unknown, dissect_unknown},
14853   /* 0x59 */  {dissect_unknown, dissect_unknown},
14854   /* 0x5a */  {dissect_unknown, dissect_unknown},
14855   /* 0x5b */  {dissect_unknown, dissect_unknown},
14856   /* 0x5c */  {dissect_unknown, dissect_unknown},
14857   /* 0x5d */  {dissect_unknown, dissect_unknown},
14858   /* 0x5e */  {dissect_unknown, dissect_unknown},
14859   /* 0x5f */  {dissect_unknown, dissect_unknown},
14860
14861   /* 0x60 */  {dissect_unknown, dissect_unknown},
14862   /* 0x61 */  {dissect_unknown, dissect_unknown},
14863   /* 0x62 */  {dissect_unknown, dissect_unknown},
14864   /* 0x63 */  {dissect_unknown, dissect_unknown},
14865   /* 0x64 */  {dissect_unknown, dissect_unknown},
14866   /* 0x65 */  {dissect_unknown, dissect_unknown},
14867   /* 0x66 */  {dissect_unknown, dissect_unknown},
14868   /* 0x67 */  {dissect_unknown, dissect_unknown},
14869   /* 0x68 */  {dissect_unknown, dissect_unknown},
14870   /* 0x69 */  {dissect_unknown, dissect_unknown},
14871   /* 0x6a */  {dissect_unknown, dissect_unknown},
14872   /* 0x6b */  {dissect_unknown, dissect_unknown},
14873   /* 0x6c */  {dissect_unknown, dissect_unknown},
14874   /* 0x6d */  {dissect_unknown, dissect_unknown},
14875   /* 0x6e */  {dissect_unknown, dissect_unknown},
14876   /* 0x6f */  {dissect_unknown, dissect_unknown},
14877
14878   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14879   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14880   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14881   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14882   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14883   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14884   /* 0x76 */  {dissect_unknown, dissect_unknown},
14885   /* 0x77 */  {dissect_unknown, dissect_unknown},
14886   /* 0x78 */  {dissect_unknown, dissect_unknown},
14887   /* 0x79 */  {dissect_unknown, dissect_unknown},
14888   /* 0x7a */  {dissect_unknown, dissect_unknown},
14889   /* 0x7b */  {dissect_unknown, dissect_unknown},
14890   /* 0x7c */  {dissect_unknown, dissect_unknown},
14891   /* 0x7d */  {dissect_unknown, dissect_unknown},
14892   /* 0x7e */  {dissect_unknown, dissect_unknown},
14893   /* 0x7f */  {dissect_unknown, dissect_unknown},
14894
14895   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14896   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14897   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14898   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14899   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14900   /* 0x85 */  {dissect_unknown, dissect_unknown},
14901   /* 0x86 */  {dissect_unknown, dissect_unknown},
14902   /* 0x87 */  {dissect_unknown, dissect_unknown},
14903   /* 0x88 */  {dissect_unknown, dissect_unknown},
14904   /* 0x89 */  {dissect_unknown, dissect_unknown},
14905   /* 0x8a */  {dissect_unknown, dissect_unknown},
14906   /* 0x8b */  {dissect_unknown, dissect_unknown},
14907   /* 0x8c */  {dissect_unknown, dissect_unknown},
14908   /* 0x8d */  {dissect_unknown, dissect_unknown},
14909   /* 0x8e */  {dissect_unknown, dissect_unknown},
14910   /* 0x8f */  {dissect_unknown, dissect_unknown},
14911
14912   /* 0x90 */  {dissect_unknown, dissect_unknown},
14913   /* 0x91 */  {dissect_unknown, dissect_unknown},
14914   /* 0x92 */  {dissect_unknown, dissect_unknown},
14915   /* 0x93 */  {dissect_unknown, dissect_unknown},
14916   /* 0x94 */  {dissect_unknown, dissect_unknown},
14917   /* 0x95 */  {dissect_unknown, dissect_unknown},
14918   /* 0x96 */  {dissect_unknown, dissect_unknown},
14919   /* 0x97 */  {dissect_unknown, dissect_unknown},
14920   /* 0x98 */  {dissect_unknown, dissect_unknown},
14921   /* 0x99 */  {dissect_unknown, dissect_unknown},
14922   /* 0x9a */  {dissect_unknown, dissect_unknown},
14923   /* 0x9b */  {dissect_unknown, dissect_unknown},
14924   /* 0x9c */  {dissect_unknown, dissect_unknown},
14925   /* 0x9d */  {dissect_unknown, dissect_unknown},
14926   /* 0x9e */  {dissect_unknown, dissect_unknown},
14927   /* 0x9f */  {dissect_unknown, dissect_unknown},
14928
14929   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14930   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14931   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14932   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14933   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14934   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14935   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14936   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14937   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14938   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14939   /* 0xaa */  {dissect_unknown, dissect_unknown},
14940   /* 0xab */  {dissect_unknown, dissect_unknown},
14941   /* 0xac */  {dissect_unknown, dissect_unknown},
14942   /* 0xad */  {dissect_unknown, dissect_unknown},
14943   /* 0xae */  {dissect_unknown, dissect_unknown},
14944   /* 0xaf */  {dissect_unknown, dissect_unknown},
14945
14946   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14947   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14948   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14949   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14950   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14951   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14952   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14953   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14954   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14955   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14956   /* 0xba */  {dissect_unknown, dissect_unknown},
14957   /* 0xbb */  {dissect_unknown, dissect_unknown},
14958   /* 0xbc */  {dissect_unknown, dissect_unknown},
14959   /* 0xbd */  {dissect_unknown, dissect_unknown},
14960   /* 0xbe */  {dissect_unknown, dissect_unknown},
14961   /* 0xbf */  {dissect_unknown, dissect_unknown},
14962
14963   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_open_print_file_response},
14964   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14965   /* 0xc2 Close Print File*/  {dissect_close_print_file_request, dissect_empty},
14966   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14967   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14968   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14969   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14970   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14971   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14972   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14973   /* 0xca */  {dissect_unknown, dissect_unknown},
14974   /* 0xcb */  {dissect_unknown, dissect_unknown},
14975   /* 0xcc */  {dissect_unknown, dissect_unknown},
14976   /* 0xcd */  {dissect_unknown, dissect_unknown},
14977   /* 0xce */  {dissect_unknown, dissect_unknown},
14978   /* 0xcf */  {dissect_unknown, dissect_unknown},
14979
14980   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14981   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14982   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14983   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14984   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14985   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14986   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14987   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14988   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14989   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14990   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14991   /* 0xdb */  {dissect_unknown, dissect_unknown},
14992   /* 0xdc */  {dissect_unknown, dissect_unknown},
14993   /* 0xdd */  {dissect_unknown, dissect_unknown},
14994   /* 0xde */  {dissect_unknown, dissect_unknown},
14995   /* 0xdf */  {dissect_unknown, dissect_unknown},
14996
14997   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14998   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14999   /* 0xe2 */  {dissect_unknown, dissect_unknown},
15000   /* 0xe3 */  {dissect_unknown, dissect_unknown},
15001   /* 0xe4 */  {dissect_unknown, dissect_unknown},
15002   /* 0xe5 */  {dissect_unknown, dissect_unknown},
15003   /* 0xe6 */  {dissect_unknown, dissect_unknown},
15004   /* 0xe7 */  {dissect_unknown, dissect_unknown},
15005   /* 0xe8 */  {dissect_unknown, dissect_unknown},
15006   /* 0xe9 */  {dissect_unknown, dissect_unknown},
15007   /* 0xea */  {dissect_unknown, dissect_unknown},
15008   /* 0xeb */  {dissect_unknown, dissect_unknown},
15009   /* 0xec */  {dissect_unknown, dissect_unknown},
15010   /* 0xed */  {dissect_unknown, dissect_unknown},
15011   /* 0xee */  {dissect_unknown, dissect_unknown},
15012   /* 0xef */  {dissect_unknown, dissect_unknown},
15013
15014   /* 0xf0 */  {dissect_unknown, dissect_unknown},
15015   /* 0xf1 */  {dissect_unknown, dissect_unknown},
15016   /* 0xf2 */  {dissect_unknown, dissect_unknown},
15017   /* 0xf3 */  {dissect_unknown, dissect_unknown},
15018   /* 0xf4 */  {dissect_unknown, dissect_unknown},
15019   /* 0xf5 */  {dissect_unknown, dissect_unknown},
15020   /* 0xf6 */  {dissect_unknown, dissect_unknown},
15021   /* 0xf7 */  {dissect_unknown, dissect_unknown},
15022   /* 0xf8 */  {dissect_unknown, dissect_unknown},
15023   /* 0xf9 */  {dissect_unknown, dissect_unknown},
15024   /* 0xfa */  {dissect_unknown, dissect_unknown},
15025   /* 0xfb */  {dissect_unknown, dissect_unknown},
15026   /* 0xfc */  {dissect_unknown, dissect_unknown},
15027   /* 0xfd */  {dissect_unknown, dissect_unknown},
15028   /* 0xfe */  {dissect_unknown, dissect_unknown},
15029   /* 0xff */  {dissect_unknown, dissect_unknown},
15030 };
15031
15032 static int
15033 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
15034 {
15035         smb_info_t *si;
15036         smb_saved_info_t *sip;
15037
15038         si = pinfo->private_data;
15039         DISSECTOR_ASSERT(si);
15040
15041         if(cmd!=0xff){
15042                 proto_item *cmd_item;
15043                 proto_tree *cmd_tree;
15044                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15045
15046                 if (check_col(pinfo->cinfo, COL_INFO)) {
15047                         if(first_pdu){
15048                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15049                                         "%s %s",
15050                                         decode_smb_name(cmd),
15051                                         (si->request)? "Request" : "Response");
15052                         } else {
15053                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15054                                         "; %s",
15055                                         decode_smb_name(cmd));
15056                         }
15057
15058                 }
15059
15060                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
15061                         "%s %s (0x%02x)",
15062                         decode_smb_name(cmd),
15063                         (si->request)?"Request":"Response",
15064                         cmd);
15065
15066                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
15067
15068                 /* we track FIDs on a per transaction basis.
15069                    if this was a request and the fid was seen in a reply
15070                    we add a "generated" fid tree for this pdu and v.v.
15071                  */
15072                 sip = si->sip;
15073                 if (sip && sip->fid) {
15074                         if( (si->request && (!sip->fid_seen_in_request))
15075                           ||((!si->request) && sip->fid_seen_in_request) ){
15076                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
15077                         }
15078                 }
15079
15080                 dissector = (si->request)?
15081                         smb_dissector[cmd].request:smb_dissector[cmd].response;
15082
15083                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
15084                 proto_item_set_end(cmd_item, tvb, offset);
15085         }
15086         return offset;
15087 }
15088
15089
15090 /* NOTE: this value_string array will also be used to access data directly by
15091  * index instead of val_to_str() since
15092  * 1, the array will always span every value from 0x00 to 0xff and
15093  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
15094  * This means that this value_string array MUST always
15095  * 1, contain all entries 0x00 to 0xff
15096  * 2, all entries must be in order.
15097  */
15098 const value_string smb_cmd_vals[] = {
15099   { 0x00, "Create Directory" },
15100   { 0x01, "Delete Directory" },
15101   { 0x02, "Open" },
15102   { 0x03, "Create" },
15103   { 0x04, "Close" },
15104   { 0x05, "Flush" },
15105   { 0x06, "Delete" },
15106   { 0x07, "Rename" },
15107   { 0x08, "Query Information" },
15108   { 0x09, "Set Information" },
15109   { 0x0A, "Read" },
15110   { 0x0B, "Write" },
15111   { 0x0C, "Lock Byte Range" },
15112   { 0x0D, "Unlock Byte Range" },
15113   { 0x0E, "Create Temp" },
15114   { 0x0F, "Create New" },
15115   { 0x10, "Check Directory" },
15116   { 0x11, "Process Exit" },
15117   { 0x12, "Seek" },
15118   { 0x13, "Lock And Read" },
15119   { 0x14, "Write And Unlock" },
15120   { 0x15, "unknown-0x15" },
15121   { 0x16, "unknown-0x16" },
15122   { 0x17, "unknown-0x17" },
15123   { 0x18, "unknown-0x18" },
15124   { 0x19, "unknown-0x19" },
15125   { 0x1A, "Read Raw" },
15126   { 0x1B, "Read MPX" },
15127   { 0x1C, "Read MPX Secondary" },
15128   { 0x1D, "Write Raw" },
15129   { 0x1E, "Write MPX" },
15130   { 0x1F, "Write MPX Secondary" },
15131   { 0x20, "Write Complete" },
15132   { 0x21, "unknown-0x21" },
15133   { 0x22, "Set Information2" },
15134   { 0x23, "Query Information2" },
15135   { 0x24, "Locking AndX" },
15136   { 0x25, "Trans" },
15137   { 0x26, "Trans Secondary" },
15138   { 0x27, "IOCTL" },
15139   { 0x28, "IOCTL Secondary" },
15140   { 0x29, "Copy" },
15141   { 0x2A, "Move" },
15142   { 0x2B, "Echo" },
15143   { 0x2C, "Write And Close" },
15144   { 0x2D, "Open AndX" },
15145   { 0x2E, "Read AndX" },
15146   { 0x2F, "Write AndX" },
15147   { 0x30, "unknown-0x30" },
15148   { 0x31, "Close And Tree Disconnect" },
15149   { 0x32, "Trans2" },
15150   { 0x33, "Trans2 Secondary" },
15151   { 0x34, "Find Close2" },
15152   { 0x35, "Find Notify Close" },
15153   { 0x36, "unknown-0x36" },
15154   { 0x37, "unknown-0x37" },
15155   { 0x38, "unknown-0x38" },
15156   { 0x39, "unknown-0x39" },
15157   { 0x3A, "unknown-0x3A" },
15158   { 0x3B, "unknown-0x3B" },
15159   { 0x3C, "unknown-0x3C" },
15160   { 0x3D, "unknown-0x3D" },
15161   { 0x3E, "unknown-0x3E" },
15162   { 0x3F, "unknown-0x3F" },
15163   { 0x40, "unknown-0x40" },
15164   { 0x41, "unknown-0x41" },
15165   { 0x42, "unknown-0x42" },
15166   { 0x43, "unknown-0x43" },
15167   { 0x44, "unknown-0x44" },
15168   { 0x45, "unknown-0x45" },
15169   { 0x46, "unknown-0x46" },
15170   { 0x47, "unknown-0x47" },
15171   { 0x48, "unknown-0x48" },
15172   { 0x49, "unknown-0x49" },
15173   { 0x4A, "unknown-0x4A" },
15174   { 0x4B, "unknown-0x4B" },
15175   { 0x4C, "unknown-0x4C" },
15176   { 0x4D, "unknown-0x4D" },
15177   { 0x4E, "unknown-0x4E" },
15178   { 0x4F, "unknown-0x4F" },
15179   { 0x50, "unknown-0x50" },
15180   { 0x51, "unknown-0x51" },
15181   { 0x52, "unknown-0x52" },
15182   { 0x53, "unknown-0x53" },
15183   { 0x54, "unknown-0x54" },
15184   { 0x55, "unknown-0x55" },
15185   { 0x56, "unknown-0x56" },
15186   { 0x57, "unknown-0x57" },
15187   { 0x58, "unknown-0x58" },
15188   { 0x59, "unknown-0x59" },
15189   { 0x5A, "unknown-0x5A" },
15190   { 0x5B, "unknown-0x5B" },
15191   { 0x5C, "unknown-0x5C" },
15192   { 0x5D, "unknown-0x5D" },
15193   { 0x5E, "unknown-0x5E" },
15194   { 0x5F, "unknown-0x5F" },
15195   { 0x60, "unknown-0x60" },
15196   { 0x61, "unknown-0x61" },
15197   { 0x62, "unknown-0x62" },
15198   { 0x63, "unknown-0x63" },
15199   { 0x64, "unknown-0x64" },
15200   { 0x65, "unknown-0x65" },
15201   { 0x66, "unknown-0x66" },
15202   { 0x67, "unknown-0x67" },
15203   { 0x68, "unknown-0x68" },
15204   { 0x69, "unknown-0x69" },
15205   { 0x6A, "unknown-0x6A" },
15206   { 0x6B, "unknown-0x6B" },
15207   { 0x6C, "unknown-0x6C" },
15208   { 0x6D, "unknown-0x6D" },
15209   { 0x6E, "unknown-0x6E" },
15210   { 0x6F, "unknown-0x6F" },
15211   { 0x70, "Tree Connect" },
15212   { 0x71, "Tree Disconnect" },
15213   { 0x72, "Negotiate Protocol" },
15214   { 0x73, "Session Setup AndX" },
15215   { 0x74, "Logoff AndX" },
15216   { 0x75, "Tree Connect AndX" },
15217   { 0x76, "unknown-0x76" },
15218   { 0x77, "unknown-0x77" },
15219   { 0x78, "unknown-0x78" },
15220   { 0x79, "unknown-0x79" },
15221   { 0x7A, "unknown-0x7A" },
15222   { 0x7B, "unknown-0x7B" },
15223   { 0x7C, "unknown-0x7C" },
15224   { 0x7D, "unknown-0x7D" },
15225   { 0x7E, "unknown-0x7E" },
15226   { 0x7F, "unknown-0x7F" },
15227   { 0x80, "Query Information Disk" },
15228   { 0x81, "Search" },
15229   { 0x82, "Find" },
15230   { 0x83, "Find Unique" },
15231   { 0x84, "Find Close" },
15232   { 0x85, "unknown-0x85" },
15233   { 0x86, "unknown-0x86" },
15234   { 0x87, "unknown-0x87" },
15235   { 0x88, "unknown-0x88" },
15236   { 0x89, "unknown-0x89" },
15237   { 0x8A, "unknown-0x8A" },
15238   { 0x8B, "unknown-0x8B" },
15239   { 0x8C, "unknown-0x8C" },
15240   { 0x8D, "unknown-0x8D" },
15241   { 0x8E, "unknown-0x8E" },
15242   { 0x8F, "unknown-0x8F" },
15243   { 0x90, "unknown-0x90" },
15244   { 0x91, "unknown-0x91" },
15245   { 0x92, "unknown-0x92" },
15246   { 0x93, "unknown-0x93" },
15247   { 0x94, "unknown-0x94" },
15248   { 0x95, "unknown-0x95" },
15249   { 0x96, "unknown-0x96" },
15250   { 0x97, "unknown-0x97" },
15251   { 0x98, "unknown-0x98" },
15252   { 0x99, "unknown-0x99" },
15253   { 0x9A, "unknown-0x9A" },
15254   { 0x9B, "unknown-0x9B" },
15255   { 0x9C, "unknown-0x9C" },
15256   { 0x9D, "unknown-0x9D" },
15257   { 0x9E, "unknown-0x9E" },
15258   { 0x9F, "unknown-0x9F" },
15259   { 0xA0, "NT Trans" },
15260   { 0xA1, "NT Trans Secondary" },
15261   { 0xA2, "NT Create AndX" },
15262   { 0xA3, "unknown-0xA3" },
15263   { 0xA4, "NT Cancel" },
15264   { 0xA5, "NT Rename" },
15265   { 0xA6, "unknown-0xA6" },
15266   { 0xA7, "unknown-0xA7" },
15267   { 0xA8, "unknown-0xA8" },
15268   { 0xA9, "unknown-0xA9" },
15269   { 0xAA, "unknown-0xAA" },
15270   { 0xAB, "unknown-0xAB" },
15271   { 0xAC, "unknown-0xAC" },
15272   { 0xAD, "unknown-0xAD" },
15273   { 0xAE, "unknown-0xAE" },
15274   { 0xAF, "unknown-0xAF" },
15275   { 0xB0, "unknown-0xB0" },
15276   { 0xB1, "unknown-0xB1" },
15277   { 0xB2, "unknown-0xB2" },
15278   { 0xB3, "unknown-0xB3" },
15279   { 0xB4, "unknown-0xB4" },
15280   { 0xB5, "unknown-0xB5" },
15281   { 0xB6, "unknown-0xB6" },
15282   { 0xB7, "unknown-0xB7" },
15283   { 0xB8, "unknown-0xB8" },
15284   { 0xB9, "unknown-0xB9" },
15285   { 0xBA, "unknown-0xBA" },
15286   { 0xBB, "unknown-0xBB" },
15287   { 0xBC, "unknown-0xBC" },
15288   { 0xBD, "unknown-0xBD" },
15289   { 0xBE, "unknown-0xBE" },
15290   { 0xBF, "unknown-0xBF" },
15291   { 0xC0, "Open Print File" },
15292   { 0xC1, "Write Print File" },
15293   { 0xC2, "Close Print File" },
15294   { 0xC3, "Get Print Queue" },
15295   { 0xC4, "unknown-0xC4" },
15296   { 0xC5, "unknown-0xC5" },
15297   { 0xC6, "unknown-0xC6" },
15298   { 0xC7, "unknown-0xC7" },
15299   { 0xC8, "unknown-0xC8" },
15300   { 0xC9, "unknown-0xC9" },
15301   { 0xCA, "unknown-0xCA" },
15302   { 0xCB, "unknown-0xCB" },
15303   { 0xCC, "unknown-0xCC" },
15304   { 0xCD, "unknown-0xCD" },
15305   { 0xCE, "unknown-0xCE" },
15306   { 0xCF, "unknown-0xCF" },
15307   { 0xD0, "Send Single Block Message" },
15308   { 0xD1, "Send Broadcast Message" },
15309   { 0xD2, "Forward User Name" },
15310   { 0xD3, "Cancel Forward" },
15311   { 0xD4, "Get Machine Name" },
15312   { 0xD5, "Send Start of Multi-block Message" },
15313   { 0xD6, "Send End of Multi-block Message" },
15314   { 0xD7, "Send Text of Multi-block Message" },
15315   { 0xD8, "SMBreadbulk" },
15316   { 0xD9, "SMBwritebulk" },
15317   { 0xDA, "SMBwritebulkdata" },
15318   { 0xDB, "unknown-0xDB" },
15319   { 0xDC, "unknown-0xDC" },
15320   { 0xDD, "unknown-0xDD" },
15321   { 0xDE, "unknown-0xDE" },
15322   { 0xDF, "unknown-0xDF" },
15323   { 0xE0, "unknown-0xE0" },
15324   { 0xE1, "unknown-0xE1" },
15325   { 0xE2, "unknown-0xE2" },
15326   { 0xE3, "unknown-0xE3" },
15327   { 0xE4, "unknown-0xE4" },
15328   { 0xE5, "unknown-0xE5" },
15329   { 0xE6, "unknown-0xE6" },
15330   { 0xE7, "unknown-0xE7" },
15331   { 0xE8, "unknown-0xE8" },
15332   { 0xE9, "unknown-0xE9" },
15333   { 0xEA, "unknown-0xEA" },
15334   { 0xEB, "unknown-0xEB" },
15335   { 0xEC, "unknown-0xEC" },
15336   { 0xED, "unknown-0xED" },
15337   { 0xEE, "unknown-0xEE" },
15338   { 0xEF, "unknown-0xEF" },
15339   { 0xF0, "unknown-0xF0" },
15340   { 0xF1, "unknown-0xF1" },
15341   { 0xF2, "unknown-0xF2" },
15342   { 0xF3, "unknown-0xF3" },
15343   { 0xF4, "unknown-0xF4" },
15344   { 0xF5, "unknown-0xF5" },
15345   { 0xF6, "unknown-0xF6" },
15346   { 0xF7, "unknown-0xF7" },
15347   { 0xF8, "unknown-0xF8" },
15348   { 0xF9, "unknown-0xF9" },
15349   { 0xFA, "unknown-0xFA" },
15350   { 0xFB, "unknown-0xFB" },
15351   { 0xFC, "unknown-0xFC" },
15352   { 0xFD, "unknown-0xFD" },
15353   { 0xFE, "SMBinvalid" },
15354   { 0xFF, "unknown-0xFF" },
15355   { 0x00, NULL },
15356 };
15357
15358 static const char *decode_smb_name(guint8 cmd)
15359 {
15360   return(smb_cmd_vals[cmd].strptr);
15361 }
15362
15363
15364
15365 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15366  * Everything TVBUFFIFIED above this line
15367  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15368
15369
15370 static void
15371 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
15372 {
15373         conv_tables_t *ct = ctarg;
15374
15375         if (ct->unmatched)
15376                 g_hash_table_destroy(ct->unmatched);
15377         if (ct->matched)
15378                 g_hash_table_destroy(ct->matched);
15379         if (ct->tid_service)
15380                 g_hash_table_destroy(ct->tid_service);
15381 }
15382
15383 static void
15384 smb_init_protocol(void)
15385 {
15386         /*
15387          * Free the hash tables attached to the conversation table
15388          * structures, and then free the list of conversation table
15389          * data structures (which doesn't free the data structures
15390          * themselves; that's done by destroying the chunk from
15391          * which they were allocated).
15392          */
15393         if (conv_tables) {
15394                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15395                 g_slist_free(conv_tables);
15396                 conv_tables = NULL;
15397         }
15398 }
15399
15400 static const value_string errcls_types[] = {
15401   { SMB_SUCCESS, "Success"},
15402   { SMB_ERRDOS, "DOS Error"},
15403   { SMB_ERRSRV, "Server Error"},
15404   { SMB_ERRHRD, "Hardware Error"},
15405   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15406   { 0, NULL }
15407 };
15408
15409 /* Error codes for the ERRSRV class */
15410
15411 static const value_string SRV_errors[] = {
15412   {SMBE_error, "Non specific error code"},
15413   {SMBE_badpw, "Bad password"},
15414   {SMBE_badtype, "Reserved"},
15415   {SMBE_access, "No permissions to perform the requested operation"},
15416   {SMBE_invnid, "TID invalid"},
15417   {SMBE_invnetname, "Invalid network name. Service not found"},
15418   {SMBE_invdevice, "Invalid device"},
15419   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15420   {SMBE_qfull, "Print queue full"},
15421   {SMBE_qtoobig, "Queued item too big"},
15422   {SMBE_qeof, "EOF on print queue dump"},
15423   {SMBE_invpfid, "Invalid print file in smb_fid"},
15424   {SMBE_smbcmd, "Unrecognised command"},
15425   {SMBE_srverror, "SMB server internal error"},
15426   {SMBE_filespecs, "Fid and pathname invalid combination"},
15427   {SMBE_badlink, "Bad link in request ???"},
15428   {SMBE_badpermits, "Access specified for a file is not valid"},
15429   {SMBE_badpid, "Bad process id in request"},
15430   {SMBE_setattrmode, "Attribute mode invalid"},
15431   {SMBE_paused, "Message server paused"},
15432   {SMBE_msgoff, "Not receiving messages"},
15433   {SMBE_noroom, "No room for message"},
15434   {SMBE_rmuns, "Too many remote usernames"},
15435   {SMBE_timeout, "Operation timed out"},
15436   {SMBE_noresource, "No resources currently available for request."},
15437   {SMBE_toomanyuids, "Too many userids"},
15438   {SMBE_baduid, "Bad userid"},
15439   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15440   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15441   {SMBE_contMPX, "Resume MPX mode"},
15442   {SMBE_badPW, "Bad Password???"},
15443   {SMBE_nosupport, "Operation not supported"},
15444   { 0, NULL}
15445 };
15446
15447 /* Error codes for the ERRHRD class */
15448
15449 static const value_string HRD_errors[] = {
15450   {SMBE_nowrite, "Read only media"},
15451   {SMBE_badunit, "Unknown device"},
15452   {SMBE_notready, "Drive not ready"},
15453   {SMBE_badcmd, "Unknown command"},
15454   {SMBE_data, "Data (CRC) error"},
15455   {SMBE_badreq, "Bad request structure length"},
15456   {SMBE_seek, "Seek error"},
15457   {SMBE_badmedia, "Unknown media type"},
15458   {SMBE_badsector, "Sector not found"},
15459   {SMBE_nopaper, "Printer out of paper"},
15460   {SMBE_write, "Write fault"},
15461   {SMBE_read, "Read fault"},
15462   {SMBE_general, "General failure"},
15463   {SMBE_badshare, "A open conflicts with an existing open"},
15464   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15465   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15466   {SMBE_FCBunavail, "No FCBs are available to process request"},
15467   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15468   {SMBE_diskfull, "Disk full???"},
15469   {0, NULL}
15470 };
15471
15472 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
15473 {
15474
15475   switch (errcls) {
15476
15477   case SMB_SUCCESS:
15478
15479     return("No Error");   /* No error ??? */
15480     break;
15481
15482   case SMB_ERRDOS:
15483
15484     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15485     break;
15486
15487   case SMB_ERRSRV:
15488
15489     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15490     break;
15491
15492   case SMB_ERRHRD:
15493
15494     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15495     break;
15496
15497   default:
15498
15499     return("Unknown error class!");
15500
15501   }
15502
15503 }
15504
15505 static const true_false_string tfs_smb_flags_lock = {
15506         "Lock&Read, Write&Unlock are supported",
15507         "Lock&Read, Write&Unlock are not supported"
15508 };
15509 static const true_false_string tfs_smb_flags_receive_buffer = {
15510         "Receive buffer has been posted",
15511         "Receive buffer has not been posted"
15512 };
15513 static const true_false_string tfs_smb_flags_caseless = {
15514         "Path names are caseless",
15515         "Path names are case sensitive"
15516 };
15517 static const true_false_string tfs_smb_flags_canon = {
15518         "Pathnames are canonicalized",
15519         "Pathnames are not canonicalized"
15520 };
15521 static const true_false_string tfs_smb_flags_oplock = {
15522         "OpLock requested/granted",
15523         "OpLock not requested/granted"
15524 };
15525 static const true_false_string tfs_smb_flags_notify = {
15526         "Notify client on all modifications",
15527         "Notify client only on open"
15528 };
15529 static const true_false_string tfs_smb_flags_response = {
15530         "Message is a response to the client/redirector",
15531         "Message is a request to the server"
15532 };
15533
15534 static int
15535 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15536 {
15537         guint8 mask;
15538         proto_item *item = NULL;
15539         proto_tree *tree = NULL;
15540
15541         mask = tvb_get_guint8(tvb, offset);
15542
15543         if(parent_tree){
15544                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15545                         "Flags: 0x%02x", mask);
15546                 tree = proto_item_add_subtree(item, ett_smb_flags);
15547         }
15548         proto_tree_add_boolean(tree, hf_smb_flags_response,
15549                 tvb, offset, 1, mask);
15550         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15551                 tvb, offset, 1, mask);
15552         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15553                 tvb, offset, 1, mask);
15554         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15555                 tvb, offset, 1, mask);
15556         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15557                 tvb, offset, 1, mask);
15558         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15559                 tvb, offset, 1, mask);
15560         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15561                 tvb, offset, 1, mask);
15562         offset += 1;
15563         return offset;
15564 }
15565
15566
15567
15568 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15569         "Long file names are allowed in the response",
15570         "Long file names are not allowed in the response"
15571 };
15572 static const true_false_string tfs_smb_flags2_ea = {
15573         "Extended attributes are supported",
15574         "Extended attributes are not supported"
15575 };
15576 static const true_false_string tfs_smb_flags2_sec_sig = {
15577         "Security signatures are supported",
15578         "Security signatures are not supported"
15579 };
15580 static const true_false_string tfs_smb_flags2_long_names_used = {
15581         "Path names in request are long file names",
15582         "Path names in request are not long file names"
15583 };
15584 static const true_false_string tfs_smb_flags2_esn = {
15585         "Extended security negotiation is supported",
15586         "Extended security negotiation is not supported"
15587 };
15588 static const true_false_string tfs_smb_flags2_dfs = {
15589         "Resolve pathnames with Dfs",
15590         "Don't resolve pathnames with Dfs"
15591 };
15592 static const true_false_string tfs_smb_flags2_roe = {
15593         "Permit reads if execute-only",
15594         "Don't permit reads if execute-only"
15595 };
15596 static const true_false_string tfs_smb_flags2_nt_error = {
15597         "Error codes are NT error codes",
15598         "Error codes are DOS error codes"
15599 };
15600 static const true_false_string tfs_smb_flags2_string = {
15601         "Strings are Unicode",
15602         "Strings are ASCII"
15603 };
15604 static int
15605 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15606 {
15607         guint16 mask;
15608         proto_item *item = NULL;
15609         proto_tree *tree = NULL;
15610
15611         mask = tvb_get_letohs(tvb, offset);
15612
15613         if(parent_tree){
15614                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15615                         "Flags2: 0x%04x", mask);
15616                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15617         }
15618
15619         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15620                 tvb, offset, 2, mask);
15621         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15622                 tvb, offset, 2, mask);
15623         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15624                 tvb, offset, 2, mask);
15625         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15626                 tvb, offset, 2, mask);
15627         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15628                 tvb, offset, 2, mask);
15629         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15630                 tvb, offset, 2, mask);
15631         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15632                 tvb, offset, 2, mask);
15633         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15634                 tvb, offset, 2, mask);
15635         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15636                 tvb, offset, 2, mask);
15637
15638         offset += 2;
15639         return offset;
15640 }
15641
15642
15643
15644 #define SMB_FLAGS_DIRN 0x80
15645
15646
15647 static void
15648 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15649 {
15650         int offset = 0;
15651         proto_item *item = NULL, *hitem = NULL;
15652         proto_tree *tree = NULL, *htree = NULL;
15653         proto_item *tmp_item=NULL;
15654         guint8          flags;
15655         guint16         flags2;
15656         smb_info_t              *si;
15657         smb_saved_info_t *sip = NULL;
15658         smb_saved_info_key_t key;
15659         smb_saved_info_key_t *new_key;
15660         guint8 errclass = 0;
15661         guint16 errcode = 0;
15662         guint32 pid_mid;
15663         conversation_t *conversation;
15664         nstime_t t, deltat;
15665
15666         si=ep_alloc(sizeof(smb_info_t));
15667
15668         top_tree=parent_tree;
15669
15670         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15671                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15672         }
15673         if (check_col(pinfo->cinfo, COL_INFO)){
15674                 col_clear(pinfo->cinfo, COL_INFO);
15675         }
15676
15677         /* start off using the local variable, we will allocate a new one if we
15678            need to*/
15679         si->cmd = tvb_get_guint8(tvb, offset+4);
15680         flags = tvb_get_guint8(tvb, offset+9);
15681         /*
15682          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
15683          * the direction flag appears never to be set, even for what appear
15684          * to be replies.  Do some SMB servers fail to set that flag,
15685          * under the assumption that the client knows it's a reply because
15686          * it received it?
15687          */
15688         si->request = !(flags&SMB_FLAGS_DIRN);
15689         flags2 = tvb_get_letohs(tvb, offset+10);
15690         if(flags2 & 0x8000){
15691                 si->unicode = TRUE; /* Mark them as Unicode */
15692         } else {
15693                 si->unicode = FALSE;
15694         }
15695         si->tid = tvb_get_letohs(tvb, offset+24);
15696         si->pid = tvb_get_letohs(tvb, offset+26);
15697         si->uid = tvb_get_letohs(tvb, offset+28);
15698         si->mid = tvb_get_letohs(tvb, offset+30);
15699         pid_mid = (si->pid << 16) | si->mid;
15700         si->info_level = -1;
15701         si->info_count = -1;
15702
15703         if (parent_tree) {
15704                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
15705                         -1, FALSE);
15706                 tree = proto_item_add_subtree(item, ett_smb);
15707
15708                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
15709                         "SMB Header");
15710
15711                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15712         }
15713
15714         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15715         offset += 4;  /* Skip the marker */
15716
15717         /* find which conversation we are part of and get the tables for that
15718            conversation*/
15719         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
15720                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15721         if(!conversation){
15722                 /* OK this is a new conversation so lets create it */
15723                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
15724                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15725         }
15726         /* see if we already have the smb data for this conversation */
15727         si->ct=conversation_get_proto_data(conversation, proto_smb);
15728         if(!si->ct){
15729                 /* No, not yet. create it and attach it to the conversation */
15730                 si->ct = se_alloc(sizeof(conv_tables_t));
15731
15732                         conv_tables = g_slist_prepend(conv_tables, si->ct);
15733                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
15734                         smb_saved_info_equal_matched);
15735                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
15736                         smb_saved_info_equal_unmatched);
15737                 si->ct->tid_service=g_hash_table_new(
15738                         smb_saved_info_hash_unmatched,
15739                         smb_saved_info_equal_unmatched);
15740                 si->ct->raw_ntlmssp = 0;
15741                 
15742                 si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
15743                 si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
15744                 si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
15745                 conversation_add_proto_data(conversation, proto_smb, si->ct);
15746         }
15747
15748         if( (si->request)
15749             &&  (si->mid==0)
15750             &&  (si->uid==0)
15751             &&  (si->pid==0)
15752             &&  (si->tid==0) ){
15753                 /* this is a broadcast SMB packet, there will not be a reply.
15754                    We dont need to do anything
15755                 */
15756                 si->unidir = TRUE;
15757         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15758                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15759                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15760                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15761                 /* Ok, we got a special request type. This request is either
15762                    an NT Cancel or a continuation relative to a real request
15763                    in an earlier packet.  In either case, we don't expect any
15764                    responses to this packet.  For continuations, any later
15765                    responses we see really just belong to the original request.
15766                    Anyway, we want to remember this packet somehow and
15767                    remember which original request it is associated with so
15768                    we can say nice things such as "This is a Cancellation to
15769                    the request in frame x", but we don't want the
15770                    request/response matching to get messed up.
15771
15772                    The only thing we do in this case is trying to find which original
15773                    request we match with and insert an entry for this "special"
15774                    request for later reference. We continue to reference the original
15775                    requests smb_saved_info_t but we dont touch it or change anything
15776                    in it.
15777                 */
15778
15779                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
15780
15781                 if(!pinfo->fd->flags.visited){
15782                         /* try to find which original call we match and if we
15783                            find it add us to the matched table. Dont touch
15784                            anything else since we dont want this one to mess
15785                            up the request/response matching. We still consider
15786                            the initial call the real request and this is only
15787                            some sort of continuation.
15788                         */
15789                         /* we only check the unmatched table and assume that the
15790                            last seen MID matching ours is the right one.
15791                            This can fail but is better than nothing
15792                         */
15793                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
15794                         if(sip!=NULL){
15795                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
15796                                 new_key->frame = pinfo->fd->num;
15797                                 new_key->pid_mid = pid_mid;
15798                                 g_hash_table_insert(si->ct->matched, new_key,
15799                                     sip);
15800                         }
15801                 } else {
15802                         /* we have seen this packet before; check the
15803                            matching table
15804                         */
15805                         key.frame = pinfo->fd->num;
15806                         key.pid_mid = pid_mid;
15807                         sip=g_hash_table_lookup(si->ct->matched, &key);
15808                         if(sip==NULL){
15809                         /*
15810                           We didn't find it.
15811                           Too bad, unfortunately there is not really much we can
15812                           do now since this means that we never saw the initial
15813                           request.
15814                          */
15815                         }
15816                 }
15817
15818
15819                 if(sip && sip->frame_req){
15820                         switch(si->cmd){
15821                         case SMB_COM_NT_CANCEL:
15822                                 tmp_item=proto_tree_add_uint(htree, hf_smb_cancel_to,
15823                                                     tvb, 0, 0, sip->frame_req);
15824                                 PROTO_ITEM_SET_GENERATED(tmp_item);
15825                                 break;
15826                         case SMB_COM_TRANSACTION_SECONDARY:
15827                         case SMB_COM_TRANSACTION2_SECONDARY:
15828                         case SMB_COM_NT_TRANSACT_SECONDARY:
15829                                 tmp_item=proto_tree_add_uint(htree, hf_smb_continuation_to,
15830                                                     tvb, 0, 0, sip->frame_req);
15831                                 PROTO_ITEM_SET_GENERATED(tmp_item);
15832                                 break;
15833                         }
15834                 } else {
15835                         switch(si->cmd){
15836                         case SMB_COM_NT_CANCEL:
15837                                 proto_tree_add_text(htree, tvb, 0, 0,
15838                                                     "Cancellation to: <unknown frame>");
15839                                 break;
15840                         case SMB_COM_TRANSACTION_SECONDARY:
15841                         case SMB_COM_TRANSACTION2_SECONDARY:
15842                         case SMB_COM_NT_TRANSACT_SECONDARY:
15843                                 proto_tree_add_text(htree, tvb, 0, 0,
15844                                                     "Continuation to: <unknown frame>");
15845                                 break;
15846                         }
15847                 }
15848         } else { /* normal bidirectional request or response */
15849                 si->unidir = FALSE;
15850
15851                 if(!pinfo->fd->flags.visited){
15852                         /* first see if we find an unmatched smb "equal" to
15853                            the current one
15854                         */
15855                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
15856                         if(sip!=NULL){
15857                                 gboolean cmd_match=FALSE;
15858
15859                                 /*
15860                                  * Make sure the SMB we found was the
15861                                  * same command, or a different command
15862                                  * that's another valid type of reply
15863                                  * to that command.
15864                                  */
15865                                 if(si->cmd==sip->cmd){
15866                                         cmd_match=TRUE;
15867                                 }
15868                                 else if(si->cmd==SMB_COM_NT_CANCEL){
15869                                         cmd_match=TRUE;
15870                                 }
15871                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
15872                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15873                                         cmd_match=TRUE;
15874                                 }
15875                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
15876                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15877                                         cmd_match=TRUE;
15878                                 }
15879                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
15880                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15881                                         cmd_match=TRUE;
15882                                 }
15883
15884                                 if( (si->request) || (!cmd_match) ) {
15885                                         /* We are processing an SMB request but there was already
15886                                            another "identical" smb request we had not matched yet.
15887                                            This must mean that either we have a retransmission or that the
15888                                            response to the previous one was lost and the client has reused
15889                                            the MID for this conversation. In either case it's not much more
15890                                            we can do than forget the old request and concentrate on the
15891                                            present one instead.
15892
15893                                            We also do this cleanup if we see that the cmd in the original
15894                                            request in sip->cmd is not compatible with the current cmd.
15895                                            This is to prevent matching errors such as if there were two
15896                                            SMBs of different cmds but with identical MID and PID values and
15897                                            if wireshark lost the first reply and the second request.
15898                                         */
15899                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
15900                                         sip=NULL; /* XXX should free it as well */
15901                                 } else {
15902                                         /* we have found a response to some
15903                                            request we have seen earlier.
15904                                            What we do now depends on whether
15905                                            this is the first response to that
15906                                            request we see (id frame_res==0) or
15907                                            if it's a response to a request
15908                                            for which we've seen an earlier
15909                                            response that's continued.
15910                                         */
15911                                         if(sip->frame_res==0 ||
15912                                            sip->flags & SMB_SIF_IS_CONTINUED){
15913                                                 /* OK, it is the first response
15914                                                    we have seen to this packet,
15915                                                    or it's a continuation of
15916                                                    a response we've seen. */
15917                                                 sip->frame_res = pinfo->fd->num;
15918                                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
15919                                                 new_key->frame = sip->frame_res;
15920                                                 new_key->pid_mid = pid_mid;
15921                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15922                                                 /* We remove the entry for unmatched since we have found a match.
15923                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
15924                                                  * and if there is packetloss in the trace (maybe due to large holes
15925                                                  * created by a sniffer device not being able to keep up
15926                                                  * with the line rate.
15927                                                  * There is a real possibility that the following would occur which is painful :
15928                                                  * 1, -> Request  MID:5
15929                                                  * 2, <- Response MID:5
15930                                                  *   3, ->Request  MID:5 (missing from capture)
15931                                                  * 4, <- Response MID:5
15932                                                  * We DONT want #4 to be presented as a response to #1
15933                                                  */
15934                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
15935                                         } else {
15936                                                 /* We have already seen another response to this MID.
15937                                                    Since the MID in reality is only something like 10 bits
15938                                                    this probably means that we just have a MID that is being
15939                                                    reused due to the small MID space and that this is a new
15940                                                    command we did not see the original request for.
15941                                                 */
15942                                                 sip=NULL;
15943                                         }
15944                                 }
15945                         }
15946                         if(si->request){
15947                                 sip = se_alloc(sizeof(smb_saved_info_t));
15948                                 sip->frame_req = pinfo->fd->num;
15949                                 sip->frame_res = 0;
15950                                 sip->req_time = pinfo->fd->abs_ts;
15951                                 sip->flags = 0;
15952                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
15953                                     == (void *)TID_IPC) {
15954                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15955                                 }
15956                                 sip->cmd = si->cmd;
15957                                 sip->extra_info = NULL;
15958                                 sip->extra_info_type = SMB_EI_NONE;
15959                                 sip->fid=0;
15960                                 sip->fid_seen_in_request=0;
15961                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
15962                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
15963                                 new_key->frame = sip->frame_req;
15964                                 new_key->pid_mid = pid_mid;
15965                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15966                         }
15967                 } else {
15968                         /* we have seen this packet before; check the
15969                            matching table.
15970                            If we haven't yet seen the reply, we won't
15971                            find the info for it; we don't need it, as
15972                            we only use it to save information, and, as
15973                            we've seen this packet before, we've already
15974                            saved the information.
15975                         */
15976                         key.frame = pinfo->fd->num;
15977                         key.pid_mid = pid_mid;
15978                         sip=g_hash_table_lookup(si->ct->matched, &key);
15979                 }
15980         }
15981
15982         /*
15983          * Pass the "sip" on to subdissectors through "si".
15984          */
15985         si->sip = sip;
15986
15987         if (sip != NULL) {
15988                 /*
15989                  * Put in fields for the frame number of the frame to which
15990                  * this is a response or the frame with the response to this
15991                  * frame - if we know the frame number (i.e., it's not 0).
15992                  */
15993                 if(si->request){
15994                         if (sip->frame_res != 0) {
15995                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15996                                 PROTO_ITEM_SET_GENERATED(tmp_item);
15997                         }
15998                 } else {
15999                         if (sip->frame_req != 0) {
16000                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16001                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16002                                 t = pinfo->fd->abs_ts;
16003                                 nstime_delta(&deltat, &t, &sip->req_time);
16004                                 tmp_item=proto_tree_add_time(htree, hf_smb_time, tvb,
16005                                     0, 0, &deltat);
16006                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16007                         }
16008                 }
16009         }
16010
16011         /* smb command */
16012         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);
16013         offset += 1;
16014
16015         if(flags2 & 0x4000){
16016                 /* handle NT 32 bit error code */
16017
16018                 si->nt_status = tvb_get_letohl(tvb, offset);
16019
16020                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16021                         TRUE);
16022                 offset += 4;
16023
16024         } else {
16025                 /* handle DOS error code & class */
16026                 errclass = tvb_get_guint8(tvb, offset);
16027                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16028                         errclass);
16029                 offset += 1;
16030
16031                 /* reserved byte */
16032                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16033                 offset += 1;
16034
16035                 /* error code */
16036                 /* XXX - the type of this field depends on the value of
16037                  * "errcls", so there is isn't a single value_string array
16038                  * fo it, so there can't be a single field for it.
16039                  */
16040                 errcode = tvb_get_letohs(tvb, offset);
16041                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16042                         offset, 2, errcode, "Error Code: %s",
16043                         decode_smb_error(errclass, errcode));
16044                 offset += 2;
16045         }
16046
16047         /* flags */
16048         offset = dissect_smb_flags(tvb, htree, offset);
16049
16050         /* flags2 */
16051         offset = dissect_smb_flags2(tvb, htree, offset);
16052
16053         /*
16054          * The document at
16055          *
16056          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16057          *
16058          * (a text version of "Microsoft Networks SMB FILE SHARING
16059          * PROTOCOL, Document Version 6.0p") says that:
16060          *
16061          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16062          *      the "High Part of PID";
16063          *
16064          *      the next four bytes are reserved;
16065          *
16066          *      the next four bytes are, for SMB-over-IPX (with no
16067          *      NetBIOS involved) two bytes of Session ID and two bytes
16068          *      of SequenceNumber.
16069          *
16070          * Network Monitor 2.x dissects the four bytes before the Session ID
16071          * as a "Key", and the two bytes after the SequenceNumber as
16072          * a "Group ID".
16073          *
16074          * The "High Part of PID" has been seen in calls other than NT
16075          * Create and X, although most of them appear to be I/O on DCE RPC
16076          * pipes opened with the NT Create and X in question.
16077          */
16078         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16079         offset += 2;
16080
16081         if (pinfo->ptype == PT_IPX &&
16082             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16083              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16084              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16085                 /*
16086                  * This is SMB-over-IPX.
16087                  * XXX - do we have to worry about "sequenced commands",
16088                  * as per the Samba document?  They say that for
16089                  * "unsequenced commands" (with a sequence number of 0),
16090                  * the Mid must be unique, but perhaps the Mid doesn't
16091                  * have to be unique for sequenced commands.  In at least
16092                  * one capture with SMB-over-IPX, however, the Mids
16093                  * are unique even for sequenced commands.
16094                  */
16095                 /* Key */
16096                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16097                     TRUE);
16098                 offset += 4;
16099
16100                 /* Session ID */
16101                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16102                     TRUE);
16103                 offset += 2;
16104
16105                 /* Sequence number */
16106                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16107                     TRUE);
16108                 offset += 2;
16109
16110                 /* Group ID */
16111                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16112                     TRUE);
16113                 offset += 2;
16114         } else {
16115                 /*
16116                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16117                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16118                  * bytes after the "High part of PID" are an 8-byte
16119                  * signature ...
16120                  */
16121                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16122                 offset += 8;
16123
16124                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16125                 offset += 2;
16126         }
16127
16128         pinfo->private_data = si;
16129
16130         /* TID
16131          * TreeConnectAndX(0x75) is special, here it is the mere fact of 
16132          * having a response that means that the share was mapped and we 
16133          * need to track it
16134          */
16135         if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
16136                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
16137         } else {
16138                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
16139         }
16140
16141         /* PID */
16142         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16143         offset += 2;
16144
16145         /* UID */
16146         offset=dissect_smb_uid(tvb, htree, offset, si);
16147
16148         /* MID */
16149         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16150         offset += 2;
16151
16152         /* tap the packet before the dissectors are called so we still get
16153            the tap listener called even if there is an exception.
16154         */
16155         tap_queue_packet(smb_tap, pinfo, si);
16156         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16157
16158         /* Append error info from this packet to info string. */
16159         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16160                 if (flags2 & 0x4000) {
16161                         /*
16162                          * The status is an NT status code; was there
16163                          * an error?
16164                          */
16165                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
16166                                 /*
16167                                  * Yes.
16168                                  */
16169                                 col_append_fstr(
16170                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16171                                         val_to_str(si->nt_status, NT_errors,
16172                                             "Unknown (0x%08X)"));
16173                         }
16174                 } else {
16175                         /*
16176                          * The status is a DOS error class and code; was
16177                          * there an error?
16178                          */
16179                         if (errclass != SMB_SUCCESS) {
16180                                 /*
16181                                  * Yes.
16182                                  */
16183                                 col_append_fstr(
16184                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16185                                         decode_smb_error(errclass, errcode));
16186                         }
16187                 }
16188         }
16189 }
16190
16191 static gboolean
16192 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16193 {
16194         /* must check that this really is a smb packet */
16195         if (!tvb_bytes_exist(tvb, 0, 4))
16196                 return FALSE;
16197
16198         if( (tvb_get_guint8(tvb, 0) != 0xff)
16199             || (tvb_get_guint8(tvb, 1) != 'S')
16200             || (tvb_get_guint8(tvb, 2) != 'M')
16201             || (tvb_get_guint8(tvb, 3) != 'B') ){
16202                 return FALSE;
16203         }
16204
16205         dissect_smb(tvb, pinfo, parent_tree);
16206         return TRUE;
16207 }
16208
16209 void
16210 proto_register_smb(void)
16211 {
16212         static hf_register_info hf[] = {
16213         { &hf_smb_cmd,
16214                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16215                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16216
16217         { &hf_smb_trans2_subcmd,
16218                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16219                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16220
16221         { &hf_smb_nt_trans_subcmd,
16222                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16223                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16224
16225         { &hf_smb_word_count,
16226                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16227                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16228
16229         { &hf_smb_byte_count,
16230                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16231                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16232
16233         { &hf_smb_response_to,
16234                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16235                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16236
16237         { &hf_smb_time,
16238                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16239                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16240
16241         { &hf_smb_response_in,
16242                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16243                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16244
16245         { &hf_smb_continuation_to,
16246                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16247                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16248
16249         { &hf_smb_nt_status,
16250                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16251                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16252
16253         { &hf_smb_error_class,
16254                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16255                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16256
16257         { &hf_smb_error_code,
16258                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16259                 NULL, 0, "DOS Error Code", HFILL }},
16260
16261         { &hf_smb_reserved,
16262                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16263                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16264
16265         { &hf_smb_sig,
16266                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16267                 NULL, 0, "Signature bytes", HFILL }},
16268
16269         { &hf_smb_key,
16270                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16271                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16272
16273         { &hf_smb_session_id,
16274                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16275                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16276
16277         { &hf_smb_sequence_num,
16278                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16279                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16280
16281         { &hf_smb_group_id,
16282                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16283                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16284
16285         { &hf_smb_pid,
16286                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16287                 NULL, 0, "Process ID", HFILL }},
16288
16289         { &hf_smb_pid_high,
16290                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16291                 NULL, 0, "Process ID High Bytes", HFILL }},
16292
16293         { &hf_smb_tid,
16294                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16295                 NULL, 0, "Tree ID", HFILL }},
16296
16297         { &hf_smb_uid,
16298                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16299                 NULL, 0, "User ID", HFILL }},
16300
16301         { &hf_smb_mid,
16302                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16303                 NULL, 0, "Multiplex ID", HFILL }},
16304
16305         { &hf_smb_flags_lock,
16306                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16307                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16308
16309         { &hf_smb_flags_receive_buffer,
16310                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16311                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16312
16313         { &hf_smb_flags_caseless,
16314                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16315                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16316
16317         { &hf_smb_flags_canon,
16318                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16319                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16320
16321         { &hf_smb_flags_oplock,
16322                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16323                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16324
16325         { &hf_smb_flags_notify,
16326                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16327                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16328
16329         { &hf_smb_flags_response,
16330                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16331                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16332
16333         { &hf_smb_flags2_long_names_allowed,
16334                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16335                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16336
16337         { &hf_smb_flags2_ea,
16338                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16339                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16340
16341         { &hf_smb_flags2_sec_sig,
16342                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16343                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16344
16345         { &hf_smb_flags2_long_names_used,
16346                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16347                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16348
16349         { &hf_smb_flags2_esn,
16350                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16351                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16352
16353         { &hf_smb_flags2_dfs,
16354                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16355                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16356
16357         { &hf_smb_flags2_roe,
16358                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16359                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16360
16361         { &hf_smb_flags2_nt_error,
16362                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16363                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16364
16365         { &hf_smb_flags2_string,
16366                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16367                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16368
16369         { &hf_smb_buffer_format,
16370                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16371                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16372
16373         { &hf_smb_dialect_name,
16374                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16375                 NULL, 0, "Name of dialect", HFILL }},
16376
16377         { &hf_smb_dialect_index,
16378                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16379                 NULL, 0, "Index of selected dialect", HFILL }},
16380
16381         { &hf_smb_max_trans_buf_size,
16382                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16383                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16384
16385         { &hf_smb_max_mpx_count,
16386                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16387                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16388
16389         { &hf_smb_max_vcs_num,
16390                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16391                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16392
16393         { &hf_smb_session_key,
16394                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16395                 NULL, 0, "Unique token identifying this session", HFILL }},
16396
16397         { &hf_smb_server_timezone,
16398                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16399                 NULL, 0, "Current timezone at server.", HFILL }},
16400
16401         { &hf_smb_encryption_key_length,
16402                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16403                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16404
16405         { &hf_smb_encryption_key,
16406                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16407                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16408
16409         { &hf_smb_primary_domain,
16410                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16411                 NULL, 0, "The server's primary domain", HFILL }},
16412
16413         { &hf_smb_server,
16414                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16415                 NULL, 0, "The name of the DC/server", HFILL }},
16416
16417         { &hf_smb_max_raw_buf_size,
16418                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16419                 NULL, 0, "Maximum raw buffer size", HFILL }},
16420
16421         { &hf_smb_server_guid,
16422                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16423                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16424
16425         { &hf_smb_security_blob_len,
16426                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16427                 NULL, 0, "Security blob length", HFILL }},
16428
16429         { &hf_smb_security_blob,
16430                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16431                 NULL, 0, "Security blob", HFILL }},
16432
16433         { &hf_smb_sm_mode16,
16434                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16435                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16436
16437         { &hf_smb_sm_password16,
16438                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16439                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16440
16441         { &hf_smb_sm_mode,
16442                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16443                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16444
16445         { &hf_smb_sm_password,
16446                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16447                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16448
16449         { &hf_smb_sm_signatures,
16450                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16451                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16452
16453         { &hf_smb_sm_sig_required,
16454                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16455                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16456
16457         { &hf_smb_rm_read,
16458                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16459                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16460
16461         { &hf_smb_rm_write,
16462                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16463                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16464
16465         { &hf_smb_server_date_time,
16466                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16467                 NULL, 0, "Current date and time at server", HFILL }},
16468
16469         { &hf_smb_server_smb_date,
16470                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16471                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16472
16473         { &hf_smb_server_smb_time,
16474                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16475                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16476
16477         { &hf_smb_server_cap_raw_mode,
16478                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16479                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16480
16481         { &hf_smb_server_cap_mpx_mode,
16482                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16483                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16484
16485         { &hf_smb_server_cap_unicode,
16486                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16487                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16488
16489         { &hf_smb_server_cap_large_files,
16490                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16491                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16492
16493         { &hf_smb_server_cap_nt_smbs,
16494                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16495                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16496
16497         { &hf_smb_server_cap_rpc_remote_apis,
16498                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16499                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16500
16501         { &hf_smb_server_cap_nt_status,
16502                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16503                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16504
16505         { &hf_smb_server_cap_level_ii_oplocks,
16506                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16507                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16508
16509         { &hf_smb_server_cap_lock_and_read,
16510                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16511                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16512
16513         { &hf_smb_server_cap_nt_find,
16514                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16515                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16516
16517         { &hf_smb_server_cap_dfs,
16518                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16519                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16520
16521         { &hf_smb_server_cap_infolevel_passthru,
16522                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16523                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16524
16525         { &hf_smb_server_cap_large_readx,
16526                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16527                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16528
16529         { &hf_smb_server_cap_large_writex,
16530                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16531                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16532
16533         { &hf_smb_server_cap_unix,
16534                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16535                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16536
16537         { &hf_smb_server_cap_reserved,
16538                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16539                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16540
16541         { &hf_smb_server_cap_bulk_transfer,
16542                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16543                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16544
16545         { &hf_smb_server_cap_compressed_data,
16546                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16547                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16548
16549         { &hf_smb_server_cap_extended_security,
16550                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16551                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16552
16553         { &hf_smb_system_time,
16554                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16555                 NULL, 0, "System Time", HFILL }},
16556
16557         { &hf_smb_unknown,
16558                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16559                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16560
16561         { &hf_smb_dir_name,
16562                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16563                 NULL, 0, "SMB Directory Name", HFILL }},
16564
16565         { &hf_smb_echo_count,
16566                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16567                 NULL, 0, "Number of times to echo data back", HFILL }},
16568
16569         { &hf_smb_echo_data,
16570                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16571                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16572
16573         { &hf_smb_echo_seq_num,
16574                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16575                 NULL, 0, "Sequence number for this echo response", HFILL }},
16576
16577         { &hf_smb_max_buf_size,
16578                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16579                 NULL, 0, "Max client buffer size", HFILL }},
16580
16581         { &hf_smb_path,
16582                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16583                 NULL, 0, "Path. Server name and share name", HFILL }},
16584
16585         { &hf_smb_service,
16586                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16587                 NULL, 0, "Service name", HFILL }},
16588
16589         { &hf_smb_password,
16590                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16591                 NULL, 0, "Password", HFILL }},
16592
16593         { &hf_smb_ansi_password,
16594                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16595                 NULL, 0, "ANSI Password", HFILL }},
16596
16597         { &hf_smb_unicode_password,
16598                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16599                 NULL, 0, "Unicode Password", HFILL }},
16600
16601         { &hf_smb_move_flags_file,
16602                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16603                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16604
16605         { &hf_smb_move_flags_dir,
16606                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16607                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16608
16609         { &hf_smb_move_flags_verify,
16610                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16611                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16612
16613         { &hf_smb_files_moved,
16614                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16615                 NULL, 0, "Number of files moved", HFILL }},
16616
16617         { &hf_smb_copy_flags_file,
16618                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16619                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16620
16621         { &hf_smb_copy_flags_dir,
16622                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16623                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16624
16625         { &hf_smb_copy_flags_dest_mode,
16626                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16627                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16628
16629         { &hf_smb_copy_flags_source_mode,
16630                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16631                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16632
16633         { &hf_smb_copy_flags_verify,
16634                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16635                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16636
16637         { &hf_smb_copy_flags_tree_copy,
16638                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16639                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16640
16641         { &hf_smb_copy_flags_ea_action,
16642                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16643                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16644
16645         { &hf_smb_count,
16646                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16647                 NULL, 0, "Count number of items/bytes", HFILL }},
16648
16649         { &hf_smb_count_low,
16650                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
16651                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
16652
16653         { &hf_smb_count_high,
16654                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
16655                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
16656
16657         { &hf_smb_file_name,
16658                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16659                 NULL, 0, "File Name", HFILL }},
16660
16661         { &hf_smb_open_function_create,
16662                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16663                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16664
16665         { &hf_smb_open_function_open,
16666                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16667                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16668
16669         { &hf_smb_fid,
16670                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16671                 NULL, 0, "FID: File ID", HFILL }},
16672
16673         { &hf_smb_file_attr_read_only_16bit,
16674                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16675                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16676
16677         { &hf_smb_file_attr_read_only_8bit,
16678                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16679                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16680
16681         { &hf_smb_file_attr_hidden_16bit,
16682                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16683                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16684
16685         { &hf_smb_file_attr_hidden_8bit,
16686                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16687                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16688
16689         { &hf_smb_file_attr_system_16bit,
16690                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16691                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16692
16693         { &hf_smb_file_attr_system_8bit,
16694                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16695                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16696
16697         { &hf_smb_file_attr_volume_16bit,
16698                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16699                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16700
16701         { &hf_smb_file_attr_volume_8bit,
16702                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16703                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16704
16705         { &hf_smb_file_attr_directory_16bit,
16706                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16707                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16708
16709         { &hf_smb_file_attr_directory_8bit,
16710                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16711                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16712
16713         { &hf_smb_file_attr_archive_16bit,
16714                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16715                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16716
16717         { &hf_smb_file_attr_archive_8bit,
16718                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16719                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16720
16721         { &hf_smb_file_attr_device,
16722                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16723                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16724
16725         { &hf_smb_file_attr_normal,
16726                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16727                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16728
16729         { &hf_smb_file_attr_temporary,
16730                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16731                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16732
16733         { &hf_smb_file_attr_sparse,
16734                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16735                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16736
16737         { &hf_smb_file_attr_reparse,
16738                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16739                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16740
16741         { &hf_smb_file_attr_compressed,
16742                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16743                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16744
16745         { &hf_smb_file_attr_offline,
16746                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16747                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16748
16749         { &hf_smb_file_attr_not_content_indexed,
16750                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16751                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16752
16753         { &hf_smb_file_attr_encrypted,
16754                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16755                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16756
16757         { &hf_smb_file_size,
16758                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16759                 NULL, 0, "File Size", HFILL }},
16760
16761         { &hf_smb_search_attribute_read_only,
16762                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16763                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16764
16765         { &hf_smb_search_attribute_hidden,
16766                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16767                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16768
16769         { &hf_smb_search_attribute_system,
16770                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16771                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16772
16773         { &hf_smb_search_attribute_volume,
16774                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16775                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16776
16777         { &hf_smb_search_attribute_directory,
16778                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16779                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16780
16781         { &hf_smb_search_attribute_archive,
16782                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16783                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16784
16785         { &hf_smb_access_mode,
16786                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16787                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16788
16789         { &hf_smb_access_sharing,
16790                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16791                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16792
16793         { &hf_smb_access_locality,
16794                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16795                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16796
16797         { &hf_smb_access_caching,
16798                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16799                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16800
16801         { &hf_smb_access_writetru,
16802                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16803                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16804
16805         { &hf_smb_create_time,
16806                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16807                 NULL, 0, "Creation Time", HFILL }},
16808
16809         { &hf_smb_modify_time,
16810                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
16811                   NULL, 0, "Modification Time", HFILL }},
16812
16813         { &hf_smb_backup_time,
16814                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
16815                   NULL, 0, "Backup time", HFILL}},
16816
16817         { &hf_smb_mac_alloc_block_count,
16818                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
16819                   NULL, 0, "Allocation Block Count", HFILL}},
16820
16821         { &hf_smb_mac_alloc_block_size,
16822                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
16823                   NULL, 0, "Allocation Block Size", HFILL}},
16824
16825         { &hf_smb_mac_free_block_count,
16826                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
16827                   NULL, 0, "Free Block Count", HFILL}},
16828
16829         { &hf_smb_mac_root_file_count,
16830                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
16831                 NULL, 0, "Root File Count", HFILL}},
16832
16833         { &hf_smb_mac_root_dir_count,
16834           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
16835             NULL, 0, "Root Directory Count", HFILL}},
16836
16837         { &hf_smb_mac_file_count,
16838           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
16839             NULL, 0, "File Count", HFILL}},
16840
16841         { &hf_smb_mac_dir_count,
16842           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
16843             NULL, 0, "Directory Count", HFILL}},
16844
16845         { &hf_smb_mac_support_flags,
16846           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
16847             NULL, 0, "Mac Support Flags", HFILL}},
16848
16849         { &hf_smb_mac_sup_access_ctrl,
16850           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
16851             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
16852
16853         { &hf_smb_mac_sup_getset_comments,
16854           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
16855             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
16856
16857         { &hf_smb_mac_sup_desktopdb_calls,
16858           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
16859             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
16860
16861         { &hf_smb_mac_sup_unique_ids,
16862           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
16863             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
16864
16865         { &hf_smb_mac_sup_streams,
16866           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
16867             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
16868
16869         { &hf_smb_create_dos_date,
16870                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16871                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16872
16873         { &hf_smb_create_dos_time,
16874                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16875                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16876
16877         { &hf_smb_last_write_time,
16878                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16879                 NULL, 0, "Time this file was last written to", HFILL }},
16880
16881         { &hf_smb_last_write_dos_date,
16882                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16883                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16884
16885         { &hf_smb_last_write_dos_time,
16886                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16887                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16888
16889         { &hf_smb_old_file_name,
16890                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
16891                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16892
16893         { &hf_smb_offset,
16894                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16895                 NULL, 0, "Offset in file", HFILL }},
16896
16897         { &hf_smb_remaining,
16898                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16899                 NULL, 0, "Remaining number of bytes", HFILL }},
16900
16901         { &hf_smb_padding,
16902                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16903                 NULL, 0, "Padding or unknown data", HFILL }},
16904
16905         { &hf_smb_file_data,
16906                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16907                 NULL, 0, "Data read/written to the file", HFILL }},
16908
16909         { &hf_smb_mac_fndrinfo,
16910                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
16911                   NULL, 0, "Finder Info", HFILL}},
16912
16913         { &hf_smb_total_data_len,
16914                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16915                 NULL, 0, "Total length of data", HFILL }},
16916
16917         { &hf_smb_data_len,
16918                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16919                 NULL, 0, "Length of data", HFILL }},
16920
16921         { &hf_smb_data_len_low,
16922                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
16923                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
16924
16925         { &hf_smb_data_len_high,
16926                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
16927                 NULL, 0, "Length of data, High 16 bits", HFILL }},
16928
16929         { &hf_smb_seek_mode,
16930                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16931                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16932
16933         { &hf_smb_access_time,
16934                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16935                 NULL, 0, "Last Access Time", HFILL }},
16936
16937         { &hf_smb_access_dos_date,
16938                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16939                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16940
16941         { &hf_smb_access_dos_time,
16942                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16943                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16944
16945         { &hf_smb_data_size,
16946                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16947                 NULL, 0, "Data Size", HFILL }},
16948
16949         { &hf_smb_alloc_size,
16950                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16951                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16952
16953         { &hf_smb_max_count,
16954                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16955                 NULL, 0, "Maximum Count", HFILL }},
16956
16957         { &hf_smb_max_count_low,
16958                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
16959                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
16960
16961         { &hf_smb_max_count_high,
16962                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
16963                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
16964
16965         { &hf_smb_min_count,
16966                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16967                 NULL, 0, "Minimum Count", HFILL }},
16968
16969         { &hf_smb_timeout,
16970                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16971                 NULL, 0, "Timeout in miliseconds", HFILL }},
16972
16973         { &hf_smb_high_offset,
16974                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16975                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16976
16977         { &hf_smb_units,
16978                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16979                 NULL, 0, "Total number of units at server", HFILL }},
16980
16981         { &hf_smb_bpu,
16982                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16983                 NULL, 0, "Blocks per unit at server", HFILL }},
16984
16985         { &hf_smb_blocksize,
16986                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16987                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16988
16989         { &hf_smb_freeunits,
16990                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16991                 NULL, 0, "Number of free units at server", HFILL }},
16992
16993         { &hf_smb_data_offset,
16994                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16995                 NULL, 0, "Data Offset", HFILL }},
16996
16997         { &hf_smb_dcm,
16998                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16999                 NULL, 0, "Data Compaction Mode", HFILL }},
17000
17001         { &hf_smb_request_mask,
17002                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17003                 NULL, 0, "Connectionless mode mask", HFILL }},
17004
17005         { &hf_smb_response_mask,
17006                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17007                 NULL, 0, "Connectionless mode mask", HFILL }},
17008
17009         { &hf_smb_search_id,
17010                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17011                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17012
17013         { &hf_smb_write_mode_write_through,
17014                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17015                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17016
17017         { &hf_smb_write_mode_return_remaining,
17018                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17019                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17020
17021         { &hf_smb_write_mode_raw,
17022                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17023                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17024
17025         { &hf_smb_write_mode_message_start,
17026                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17027                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17028
17029         { &hf_smb_write_mode_connectionless,
17030                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17031                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17032
17033         { &hf_smb_resume_key_len,
17034                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17035                 NULL, 0, "Resume Key length", HFILL }},
17036
17037         { &hf_smb_resume_find_id,
17038                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17039                 NULL, 0, "Handle for Find operation", HFILL }},
17040
17041         { &hf_smb_resume_server_cookie,
17042                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17043                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17044
17045         { &hf_smb_resume_client_cookie,
17046                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17047                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17048
17049         { &hf_smb_andxoffset,
17050                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17051                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17052
17053         { &hf_smb_lock_type_large,
17054                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17055                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17056
17057         { &hf_smb_lock_type_cancel,
17058                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17059                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17060
17061         { &hf_smb_lock_type_change,
17062                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17063                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17064
17065         { &hf_smb_lock_type_oplock,
17066                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17067                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17068
17069         { &hf_smb_lock_type_shared,
17070                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17071                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17072
17073         { &hf_smb_locking_ol,
17074                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17075                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17076
17077         { &hf_smb_number_of_locks,
17078                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17079                 NULL, 0, "Number of lock requests in this request", HFILL }},
17080
17081         { &hf_smb_number_of_unlocks,
17082                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17083                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17084
17085         { &hf_smb_lock_long_length,
17086                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17087                 NULL, 0, "Length of lock/unlock region", HFILL }},
17088
17089         { &hf_smb_lock_long_offset,
17090                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17091                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17092
17093         { &hf_smb_file_type,
17094                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17095                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17096
17097         { &hf_smb_ipc_state_nonblocking,
17098                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17099                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17100
17101         { &hf_smb_ipc_state_endpoint,
17102                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17103                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17104
17105         { &hf_smb_ipc_state_pipe_type,
17106                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17107                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17108
17109         { &hf_smb_ipc_state_read_mode,
17110                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17111                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17112
17113         { &hf_smb_ipc_state_icount,
17114                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17115                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17116
17117         { &hf_smb_server_fid,
17118                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17119                 NULL, 0, "Server unique File ID", HFILL }},
17120
17121         { &hf_smb_open_flags_add_info,
17122                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17123                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17124
17125         { &hf_smb_open_flags_ex_oplock,
17126                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17127                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17128
17129         { &hf_smb_open_flags_batch_oplock,
17130                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17131                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17132
17133         { &hf_smb_open_flags_ealen,
17134                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17135                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17136
17137         { &hf_smb_open_action_open,
17138                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17139                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17140
17141         { &hf_smb_open_action_lock,
17142                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17143                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17144
17145         { &hf_smb_vc_num,
17146                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17147                 NULL, 0, "VC Number", HFILL }},
17148
17149         { &hf_smb_password_len,
17150                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17151                 NULL, 0, "Length of password", HFILL }},
17152
17153         { &hf_smb_ansi_password_len,
17154                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17155                 NULL, 0, "Length of ANSI password", HFILL }},
17156
17157         { &hf_smb_unicode_password_len,
17158                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17159                 NULL, 0, "Length of Unicode password", HFILL }},
17160
17161         { &hf_smb_account,
17162                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17163                 NULL, 0, "Account, username", HFILL }},
17164
17165         { &hf_smb_os,
17166                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17167                 NULL, 0, "Which OS we are running", HFILL }},
17168
17169         { &hf_smb_lanman,
17170                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17171                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17172
17173         { &hf_smb_setup_action_guest,
17174                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17175                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17176
17177         { &hf_smb_fs,
17178                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17179                 NULL, 0, "Native File System", HFILL }},
17180
17181         { &hf_smb_connect_flags_dtid,
17182                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17183                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17184
17185         { &hf_smb_connect_support_search,
17186                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17187                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17188
17189         { &hf_smb_connect_support_in_dfs,
17190                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17191                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17192
17193         { &hf_smb_max_setup_count,
17194                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17195                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17196
17197         { &hf_smb_total_param_count,
17198                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17199                 NULL, 0, "Total number of parameter bytes", HFILL }},
17200
17201         { &hf_smb_total_data_count,
17202                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17203                 NULL, 0, "Total number of data bytes", HFILL }},
17204
17205         { &hf_smb_max_param_count,
17206                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17207                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17208
17209         { &hf_smb_max_data_count,
17210                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17211                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17212
17213         { &hf_smb_param_disp16,
17214                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17215                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17216
17217         { &hf_smb_param_count16,
17218                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17219                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17220
17221         { &hf_smb_param_offset16,
17222                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17223                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17224
17225         { &hf_smb_param_disp32,
17226                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17227                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17228
17229         { &hf_smb_param_count32,
17230                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17231                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17232
17233         { &hf_smb_param_offset32,
17234                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17235                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17236
17237         { &hf_smb_data_count16,
17238                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17239                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17240
17241         { &hf_smb_data_disp16,
17242                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17243                 NULL, 0, "Data Displacement", HFILL }},
17244
17245         { &hf_smb_data_offset16,
17246                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17247                 NULL, 0, "Data Offset", HFILL }},
17248
17249         { &hf_smb_data_count32,
17250                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17251                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17252
17253         { &hf_smb_data_disp32,
17254                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17255                 NULL, 0, "Data Displacement", HFILL }},
17256
17257         { &hf_smb_data_offset32,
17258                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17259                 NULL, 0, "Data Offset", HFILL }},
17260
17261         { &hf_smb_setup_count,
17262                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17263                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17264
17265         { &hf_smb_nt_ioctl_isfsctl,
17266                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17267                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17268
17269         { &hf_smb_nt_ioctl_flags_root_handle,
17270                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17271                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17272
17273         { &hf_smb_nt_notify_action,
17274                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17275                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17276
17277         { &hf_smb_nt_notify_watch_tree,
17278                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17279                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17280
17281         { &hf_smb_nt_notify_stream_write,
17282                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17283                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17284
17285         { &hf_smb_nt_notify_stream_size,
17286                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17287                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17288
17289         { &hf_smb_nt_notify_stream_name,
17290                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17291                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17292
17293         { &hf_smb_nt_notify_security,
17294                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17295                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17296
17297         { &hf_smb_nt_notify_ea,
17298                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17299                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17300
17301         { &hf_smb_nt_notify_creation,
17302                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17303                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17304
17305         { &hf_smb_nt_notify_last_access,
17306                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17307                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17308
17309         { &hf_smb_nt_notify_last_write,
17310                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17311                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17312
17313         { &hf_smb_nt_notify_size,
17314                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17315                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17316
17317         { &hf_smb_nt_notify_attributes,
17318                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17319                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17320
17321         { &hf_smb_nt_notify_dir_name,
17322                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17323                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17324
17325         { &hf_smb_nt_notify_file_name,
17326                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17327                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17328
17329         { &hf_smb_root_dir_fid,
17330                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17331                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17332
17333         { &hf_smb_alloc_size64,
17334                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17335                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17336
17337         { &hf_smb_nt_create_disposition,
17338                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17339                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17340
17341         { &hf_smb_sd_length,
17342                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17343                 NULL, 0, "Total length of security descriptor", HFILL }},
17344
17345         { &hf_smb_ea_list_length,
17346                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17347                 NULL, 0, "Total length of extended attributes", HFILL }},
17348
17349         { &hf_smb_ea_flags,
17350                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17351                 NULL, 0, "EA Flags", HFILL }},
17352
17353         { &hf_smb_ea_name_length,
17354                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17355                 NULL, 0, "EA Name Length", HFILL }},
17356
17357         { &hf_smb_ea_data_length,
17358                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17359                 NULL, 0, "EA Data Length", HFILL }},
17360
17361         { &hf_smb_ea_name,
17362                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17363                 NULL, 0, "EA Name", HFILL }},
17364
17365         { &hf_smb_ea_data,
17366                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17367                 NULL, 0, "EA Data", HFILL }},
17368
17369         { &hf_smb_file_name_len,
17370                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17371                 NULL, 0, "Length of File Name", HFILL }},
17372
17373         { &hf_smb_nt_impersonation_level,
17374                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17375                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17376
17377         { &hf_smb_nt_security_flags_context_tracking,
17378                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17379                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17380
17381         { &hf_smb_nt_security_flags_effective_only,
17382                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17383                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17384
17385         { &hf_smb_nt_access_mask_generic_read,
17386                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17387                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17388
17389         { &hf_smb_nt_access_mask_generic_write,
17390                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17391                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17392
17393         { &hf_smb_nt_access_mask_generic_execute,
17394                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17395                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17396
17397         { &hf_smb_nt_access_mask_generic_all,
17398                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17399                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17400
17401         { &hf_smb_nt_access_mask_maximum_allowed,
17402                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17403                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17404
17405         { &hf_smb_nt_access_mask_system_security,
17406                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17407                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17408
17409         { &hf_smb_nt_access_mask_synchronize,
17410                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17411                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17412
17413         { &hf_smb_nt_access_mask_write_owner,
17414                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17415                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17416
17417         { &hf_smb_nt_access_mask_write_dac,
17418                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17419                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17420
17421         { &hf_smb_nt_access_mask_read_control,
17422                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17423                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17424
17425         { &hf_smb_nt_access_mask_delete,
17426                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17427                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17428
17429         { &hf_smb_nt_access_mask_write_attributes,
17430                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17431                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17432
17433         { &hf_smb_nt_access_mask_read_attributes,
17434                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17435                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17436
17437         { &hf_smb_nt_access_mask_delete_child,
17438                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17439                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17440
17441         /*
17442          * "Execute" for files, "traverse" for directories.
17443          */
17444         { &hf_smb_nt_access_mask_execute,
17445                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17446                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17447
17448         { &hf_smb_nt_access_mask_write_ea,
17449                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17450                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17451
17452         { &hf_smb_nt_access_mask_read_ea,
17453                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17454                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17455
17456         /*
17457          * "Append data" for files, "add subdirectory" for directories,
17458          * "create pipe instance" for named pipes.
17459          */
17460         { &hf_smb_nt_access_mask_append,
17461                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17462                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17463
17464         /*
17465          * "Write data" for files and pipes, "add file" for directory.
17466          */
17467         { &hf_smb_nt_access_mask_write,
17468                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17469                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17470
17471         /*
17472          * "Read data" for files and pipes, "list directory" for directory.
17473          */
17474         { &hf_smb_nt_access_mask_read,
17475                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17476                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17477
17478         { &hf_smb_nt_create_bits_oplock,
17479                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17480                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17481
17482         { &hf_smb_nt_create_bits_boplock,
17483                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17484                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17485
17486         { &hf_smb_nt_create_bits_dir,
17487                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17488                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17489
17490         { &hf_smb_nt_create_bits_ext_resp,
17491           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
17492             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
17493
17494         { &hf_smb_nt_create_options_directory_file,
17495                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17496                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17497
17498         { &hf_smb_nt_create_options_write_through,
17499                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17500                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17501
17502         { &hf_smb_nt_create_options_sequential_only,
17503                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17504                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17505
17506         { &hf_smb_nt_create_options_no_intermediate_buffering,
17507                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
17508                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
17509
17510         { &hf_smb_nt_create_options_sync_io_alert,
17511                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17512                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17513
17514         { &hf_smb_nt_create_options_sync_io_nonalert,
17515                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17516                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17517
17518         { &hf_smb_nt_create_options_non_directory_file,
17519                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17520                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17521
17522         { &hf_smb_nt_create_options_create_tree_connection,
17523                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
17524                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
17525
17526         { &hf_smb_nt_create_options_complete_if_oplocked,
17527                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
17528                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
17529
17530         { &hf_smb_nt_create_options_no_ea_knowledge,
17531                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17532                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17533
17534         { &hf_smb_nt_create_options_eight_dot_three_only,
17535                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17536                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17537
17538         { &hf_smb_nt_create_options_random_access,
17539                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17540                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17541
17542         { &hf_smb_nt_create_options_delete_on_close,
17543                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17544                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17545         { &hf_smb_nt_create_options_open_by_fileid,
17546                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
17547                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
17548
17549         { &hf_smb_nt_create_options_backup_intent,
17550                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
17551                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
17552
17553         { &hf_smb_nt_create_options_no_compression,
17554                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
17555                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
17556
17557         { &hf_smb_nt_create_options_reserve_opfilter,
17558                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
17559                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
17560
17561         { &hf_smb_nt_create_options_open_reparse_point,
17562                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
17563                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
17564
17565         { &hf_smb_nt_create_options_open_no_recall,
17566                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
17567                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
17568
17569         { &hf_smb_nt_create_options_open_for_free_space_query,
17570                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
17571                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
17572
17573         { &hf_smb_nt_share_access_read,
17574                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17575                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
17576
17577         { &hf_smb_nt_share_access_write,
17578                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17579                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
17580
17581         { &hf_smb_nt_share_access_delete,
17582                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17583                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, "", HFILL }},
17584
17585         { &hf_smb_file_eattr_read_only,
17586                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17587                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17588
17589         { &hf_smb_file_eattr_hidden,
17590                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17591                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17592
17593         { &hf_smb_file_eattr_system,
17594                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17595                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17596
17597         { &hf_smb_file_eattr_volume,
17598                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
17599                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17600
17601         { &hf_smb_file_eattr_directory,
17602                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
17603                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17604
17605         { &hf_smb_file_eattr_archive,
17606                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17607                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17608
17609         { &hf_smb_file_eattr_device,
17610                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17611                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17612
17613         { &hf_smb_file_eattr_normal,
17614                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17615                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17616
17617         { &hf_smb_file_eattr_temporary,
17618                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17619                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17620
17621         { &hf_smb_file_eattr_sparse,
17622                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17623                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17624
17625         { &hf_smb_file_eattr_reparse,
17626                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17627                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17628
17629         { &hf_smb_file_eattr_compressed,
17630                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17631                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17632
17633         { &hf_smb_file_eattr_offline,
17634                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17635                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17636
17637         { &hf_smb_file_eattr_not_content_indexed,
17638                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17639                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17640
17641         { &hf_smb_file_eattr_encrypted,
17642                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17643                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17644
17645         { &hf_smb_sec_desc_len,
17646                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17647                 NULL, 0, "Security Descriptor Length", HFILL }},
17648
17649         { &hf_smb_nt_qsd_owner,
17650                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17651                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17652
17653         { &hf_smb_nt_qsd_group,
17654                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17655                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17656
17657         { &hf_smb_nt_qsd_dacl,
17658                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17659                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17660
17661         { &hf_smb_nt_qsd_sacl,
17662                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17663                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17664
17665         { &hf_smb_extended_attributes,
17666                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17667                 NULL, 0, "Extended Attributes", HFILL }},
17668
17669         { &hf_smb_oplock_level,
17670                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17671                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17672
17673         { &hf_smb_create_action,
17674                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17675                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
17676
17677         { &hf_smb_file_id,
17678                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17679                 NULL, 0, "Server unique file ID", HFILL }},
17680
17681         { &hf_smb_ea_error_offset,
17682                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
17683                 NULL, 0, "Offset into EA list if EA error", HFILL }},
17684
17685         { &hf_smb_end_of_file,
17686                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
17687                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
17688
17689         { &hf_smb_replace,
17690                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
17691                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
17692
17693         { &hf_smb_root_dir_handle,
17694                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
17695                 NULL, 0, "Root directory handle", HFILL }},
17696
17697         { &hf_smb_target_name_len,
17698                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
17699                 NULL, 0, "Length of target file name", HFILL }},
17700
17701         { &hf_smb_target_name,
17702                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
17703                 NULL, 0, "Target file name", HFILL }},
17704
17705         { &hf_smb_device_type,
17706                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
17707                 VALS(device_type_vals), 0, "Type of device", HFILL }},
17708
17709         { &hf_smb_is_directory,
17710                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
17711                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
17712
17713         { &hf_smb_next_entry_offset,
17714                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
17715                 NULL, 0, "Offset to next entry", HFILL }},
17716
17717         { &hf_smb_change_time,
17718                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
17719                 NULL, 0, "Last Change Time", HFILL }},
17720
17721         { &hf_smb_setup_len,
17722                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
17723                 NULL, 0, "Length of printer setup data", HFILL }},
17724
17725         { &hf_smb_print_mode,
17726                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
17727                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
17728
17729         { &hf_smb_print_identifier,
17730                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
17731                 NULL, 0, "Identifier string for this print job", HFILL }},
17732
17733         { &hf_smb_restart_index,
17734                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
17735                 NULL, 0, "Index of entry after last returned", HFILL }},
17736
17737         { &hf_smb_print_queue_date,
17738                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
17739                 NULL, 0, "Date when this entry was queued", HFILL }},
17740
17741         { &hf_smb_print_queue_dos_date,
17742                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
17743                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
17744
17745         { &hf_smb_print_queue_dos_time,
17746                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17747                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17748
17749         { &hf_smb_print_status,
17750                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17751                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17752
17753         { &hf_smb_print_spool_file_number,
17754                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17755                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17756
17757         { &hf_smb_print_spool_file_size,
17758                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17759                 NULL, 0, "Number of bytes in spool file", HFILL }},
17760
17761         { &hf_smb_print_spool_file_name,
17762                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
17763                 NULL, 0, "Name of client that submitted this job", HFILL }},
17764
17765         { &hf_smb_start_index,
17766                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17767                 NULL, 0, "First queue entry to return", HFILL }},
17768
17769         { &hf_smb_originator_name,
17770                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17771                 NULL, 0, "Name of sender of message", HFILL }},
17772
17773         { &hf_smb_destination_name,
17774                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17775                 NULL, 0, "Name of recipient of message", HFILL }},
17776
17777         { &hf_smb_message_len,
17778                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17779                 NULL, 0, "Length of message", HFILL }},
17780
17781         { &hf_smb_message,
17782                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17783                 NULL, 0, "Message text", HFILL }},
17784
17785         { &hf_smb_mgid,
17786                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17787                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17788
17789         { &hf_smb_forwarded_name,
17790                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17791                 NULL, 0, "Recipient name being forwarded", HFILL }},
17792
17793         { &hf_smb_machine_name,
17794                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17795                 NULL, 0, "Name of target machine", HFILL }},
17796
17797         { &hf_smb_cancel_to,
17798                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
17799                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17800
17801         { &hf_smb_trans_name,
17802                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17803                 NULL, 0, "Name of transaction", HFILL }},
17804
17805         { &hf_smb_transaction_flags_dtid,
17806                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17807                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17808
17809         { &hf_smb_transaction_flags_owt,
17810                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17811                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17812
17813         { &hf_smb_search_count,
17814                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17815                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17816
17817         { &hf_smb_search_pattern,
17818                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17819                 NULL, 0, "Search Pattern", HFILL }},
17820
17821         { &hf_smb_ff2_backup,
17822                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17823                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17824
17825         { &hf_smb_ff2_continue,
17826                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17827                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17828
17829         { &hf_smb_ff2_resume,
17830                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17831                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17832
17833         { &hf_smb_ff2_close_eos,
17834                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17835                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17836
17837         { &hf_smb_ff2_close,
17838                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17839                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17840
17841         { &hf_smb_ff2_information_level,
17842                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17843                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17844
17845         { &hf_smb_qpi_loi,
17846                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
17847                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
17848
17849         { &hf_smb_spi_loi,
17850                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
17851                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
17852
17853 #if 0
17854         { &hf_smb_sfi_writetru,
17855                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17856                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17857
17858         { &hf_smb_sfi_caching,
17859                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17860                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17861 #endif
17862
17863         { &hf_smb_storage_type,
17864                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17865                 NULL, 0, "Type of storage", HFILL }},
17866
17867         { &hf_smb_resume,
17868                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17869                 NULL, 0, "Resume Key", HFILL }},
17870
17871         { &hf_smb_max_referral_level,
17872                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17873                 NULL, 0, "Latest referral version number understood", HFILL }},
17874
17875         { &hf_smb_qfsi_information_level,
17876                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
17877                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17878
17879         { &hf_smb_nt_rename_level,
17880                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17881                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17882
17883         { &hf_smb_cluster_count,
17884                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17885                 NULL, 0, "Number of clusters", HFILL }},
17886
17887         { &hf_smb_number_of_links,
17888                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17889                 NULL, 0, "Number of hard links to the file", HFILL }},
17890
17891         { &hf_smb_delete_pending,
17892                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17893                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17894
17895         { &hf_smb_index_number,
17896                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
17897                 NULL, 0, "File system unique identifier", HFILL }},
17898
17899         { &hf_smb_position,
17900                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
17901                 NULL, 0, "File position", HFILL }},
17902
17903         { &hf_smb_current_offset,
17904                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17905                 NULL, 0, "Current offset in the file", HFILL }},
17906
17907         { &hf_smb_t2_alignment,
17908                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17909                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17910
17911         { &hf_smb_t2_stream_name_length,
17912                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17913                 NULL, 0, "Length of stream name", HFILL }},
17914
17915         { &hf_smb_t2_stream_size,
17916                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17917                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17918
17919         { &hf_smb_t2_stream_name,
17920                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17921                 NULL, 0, "Name of the stream", HFILL }},
17922
17923         { &hf_smb_t2_compressed_file_size,
17924                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17925                 NULL, 0, "Size of the compressed file", HFILL }},
17926
17927         { &hf_smb_t2_compressed_format,
17928                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17929                 NULL, 0, "Compression algorithm used", HFILL }},
17930
17931         { &hf_smb_t2_compressed_unit_shift,
17932                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17933                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17934
17935         { &hf_smb_t2_compressed_chunk_shift,
17936                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17937                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17938
17939         { &hf_smb_t2_compressed_cluster_shift,
17940                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17941                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17942
17943         { &hf_smb_t2_marked_for_deletion,
17944                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
17945                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
17946
17947         { &hf_smb_dfs_path_consumed,
17948                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17949                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17950
17951         { &hf_smb_dfs_num_referrals,
17952                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17953                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17954
17955         { &hf_smb_get_dfs_server_hold_storage,
17956                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17957                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17958
17959         { &hf_smb_get_dfs_fielding,
17960                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17961                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17962
17963         { &hf_smb_dfs_referral_version,
17964                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17965                 NULL, 0, "Version of referral element", HFILL }},
17966
17967         { &hf_smb_dfs_referral_size,
17968                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17969                 NULL, 0, "Size of referral element", HFILL }},
17970
17971         { &hf_smb_dfs_referral_server_type,
17972                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17973                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17974
17975         { &hf_smb_dfs_referral_flags_strip,
17976                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17977                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17978
17979         { &hf_smb_dfs_referral_node_offset,
17980                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17981                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17982
17983         { &hf_smb_dfs_referral_node,
17984                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17985                 NULL, 0, "Name of entity to visit next", HFILL }},
17986
17987         { &hf_smb_dfs_referral_proximity,
17988                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17989                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17990
17991         { &hf_smb_dfs_referral_ttl,
17992                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17993                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17994
17995         { &hf_smb_dfs_referral_path_offset,
17996                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17997                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17998
17999         { &hf_smb_dfs_referral_path,
18000                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18001                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18002
18003         { &hf_smb_dfs_referral_alt_path_offset,
18004                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18005                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18006
18007         { &hf_smb_dfs_referral_alt_path,
18008                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18009                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18010
18011         { &hf_smb_end_of_search,
18012                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18013                 NULL, 0, "Was last entry returned?", HFILL }},
18014
18015         { &hf_smb_last_name_offset,
18016                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18017                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18018
18019         { &hf_smb_fn_information_level,
18020                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18021                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18022
18023         { &hf_smb_monitor_handle,
18024                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18025                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18026
18027         { &hf_smb_change_count,
18028                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18029                 NULL, 0, "Number of changes to wait for", HFILL }},
18030
18031         { &hf_smb_file_index,
18032                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18033                 NULL, 0, "File index", HFILL }},
18034
18035         { &hf_smb_short_file_name,
18036                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18037                 NULL, 0, "Short (8.3) File Name", HFILL }},
18038
18039         { &hf_smb_short_file_name_len,
18040                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18041                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18042
18043         { &hf_smb_fs_id,
18044                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18045                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18046
18047         { &hf_smb_sector_unit,
18048                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18049                 NULL, 0, "Sectors per allocation unit", HFILL }},
18050
18051         { &hf_smb_fs_units,
18052                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18053                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18054
18055         { &hf_smb_fs_sector,
18056                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18057                 NULL, 0, "Bytes per sector", HFILL }},
18058
18059         { &hf_smb_avail_units,
18060                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18061                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18062
18063         { &hf_smb_volume_serial_num,
18064                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18065                 NULL, 0, "Volume serial number", HFILL }},
18066
18067         { &hf_smb_volume_label_len,
18068                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18069                 NULL, 0, "Length of volume label", HFILL }},
18070
18071         { &hf_smb_volume_label,
18072                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18073                 NULL, 0, "Volume label", HFILL }},
18074
18075         { &hf_smb_free_alloc_units64,
18076                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18077                 NULL, 0, "Number of free allocation units", HFILL }},
18078
18079         { &hf_smb_caller_free_alloc_units64,
18080                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18081                 NULL, 0, "Number of caller free allocation units", HFILL }},
18082
18083         { &hf_smb_actual_free_alloc_units64,
18084                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18085                 NULL, 0, "Number of actual free allocation units", HFILL }},
18086
18087         { &hf_smb_soft_quota_limit,
18088                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18089                 NULL, 0, "Soft Quota treshold", HFILL }},
18090
18091         { &hf_smb_hard_quota_limit,
18092                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18093                 NULL, 0, "Hard Quota limit", HFILL }},
18094
18095         { &hf_smb_user_quota_used,
18096                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18097                 NULL, 0, "How much Quota is used by this user", HFILL }},
18098
18099         { &hf_smb_max_name_len,
18100                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18101                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18102
18103         { &hf_smb_fs_name_len,
18104                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18105                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18106
18107         { &hf_smb_fs_name,
18108                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18109                 NULL, 0, "Name of filesystem", HFILL }},
18110
18111         { &hf_smb_device_char_removable,
18112                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18113                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18114
18115         { &hf_smb_device_char_read_only,
18116                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18117                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18118
18119         { &hf_smb_device_char_floppy,
18120                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18121                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18122
18123         { &hf_smb_device_char_write_once,
18124                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18125                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18126
18127         { &hf_smb_device_char_remote,
18128                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18129                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18130
18131         { &hf_smb_device_char_mounted,
18132                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18133                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18134
18135         { &hf_smb_device_char_virtual,
18136                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18137                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18138
18139         { &hf_smb_fs_attr_css,
18140                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18141                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18142
18143         { &hf_smb_fs_attr_cpn,
18144                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18145                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18146
18147         { &hf_smb_fs_attr_uod,
18148                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
18149                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
18150
18151         { &hf_smb_fs_attr_pacls,
18152                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18153                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
18154
18155         { &hf_smb_fs_attr_fc,
18156                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18157                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
18158
18159         { &hf_smb_fs_attr_vq,
18160                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18161                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
18162
18163         { &hf_smb_fs_attr_ssf,
18164                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
18165                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
18166
18167         { &hf_smb_fs_attr_srp,
18168                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
18169                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
18170
18171         { &hf_smb_fs_attr_srs,
18172                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
18173                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
18174
18175         { &hf_smb_fs_attr_sla,
18176                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
18177                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
18178
18179         { &hf_smb_fs_attr_vic,
18180                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
18181                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
18182
18183         { &hf_smb_fs_attr_soids,
18184                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
18185                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
18186
18187         { &hf_smb_fs_attr_se,
18188                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
18189                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
18190
18191         { &hf_smb_fs_attr_ns,
18192                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
18193                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
18194
18195         { &hf_smb_fs_attr_rov,
18196                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
18197                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
18198
18199         { &hf_smb_user_quota_offset,
18200                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18201                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18202
18203         { &hf_smb_pipe_write_len,
18204                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18205                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18206
18207         { &hf_smb_quota_flags_deny_disk,
18208                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18209                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18210
18211         { &hf_smb_quota_flags_log_limit,
18212                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18213                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18214
18215         { &hf_smb_quota_flags_log_warning,
18216                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18217                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18218
18219         { &hf_smb_quota_flags_enabled,
18220                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18221                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18222
18223         { &hf_smb_segment_overlap,
18224                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18225                         "Fragment overlaps with other fragments", HFILL }},
18226
18227         { &hf_smb_segment_overlap_conflict,
18228                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18229                         "Overlapping fragments contained conflicting data", HFILL }},
18230
18231         { &hf_smb_segment_multiple_tails,
18232                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18233                         "Several tails were found when defragmenting the packet", HFILL }},
18234
18235         { &hf_smb_segment_too_long_fragment,
18236                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18237                         "Fragment contained data past end of packet", HFILL }},
18238
18239         { &hf_smb_segment_error,
18240                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18241                         "Defragmentation error due to illegal fragments", HFILL }},
18242
18243         { &hf_smb_opened_in,
18244                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18245                         "The frame this fid was opened", HFILL }},
18246
18247         { &hf_smb_closed_in,
18248                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18249                         "The frame this fid was closed", HFILL }},
18250
18251         { &hf_smb_mapped_in,
18252                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18253                         "The frame this share was mapped", HFILL }},
18254
18255         { &hf_smb_unmapped_in,
18256                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18257                         "The frame this share was unmapped", HFILL }},
18258
18259         { &hf_smb_segment,
18260                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18261                         "SMB Segment", HFILL }},
18262
18263         { &hf_smb_segments,
18264                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18265                         "SMB Segments", HFILL }},
18266
18267         { &hf_smb_unix_major_version,
18268           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18269             NULL, 0, "UNIX Major Version", HFILL }},
18270
18271         { &hf_smb_unix_minor_version,
18272           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18273             NULL, 0, "UNIX Minor Version", HFILL }},
18274
18275         { &hf_smb_unix_capability_fcntl,
18276           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18277                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18278
18279         { &hf_smb_unix_capability_posix_acl,
18280           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18281                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18282
18283         { &hf_smb_file_access_mask_read_data,
18284           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
18285                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18286
18287         { &hf_smb_file_access_mask_write_data,
18288           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
18289                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18290
18291         { &hf_smb_file_access_mask_append_data,
18292           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
18293                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18294
18295         { &hf_smb_file_access_mask_read_ea,
18296           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
18297                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18298
18299         { &hf_smb_file_access_mask_write_ea,
18300           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
18301                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18302
18303         { &hf_smb_file_access_mask_execute,
18304           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
18305                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18306
18307         { &hf_smb_file_access_mask_read_attribute,
18308           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
18309                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18310
18311         { &hf_smb_file_access_mask_write_attribute,
18312           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
18313                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18314
18315         { &hf_smb_dir_access_mask_list,
18316           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
18317                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18318
18319         { &hf_smb_dir_access_mask_add_file,
18320           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
18321                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18322
18323         { &hf_smb_dir_access_mask_add_subdir,
18324           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
18325                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18326
18327         { &hf_smb_dir_access_mask_read_ea,
18328           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
18329                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18330
18331         { &hf_smb_dir_access_mask_write_ea,
18332           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
18333                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18334
18335         { &hf_smb_dir_access_mask_traverse,
18336           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
18337                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18338
18339         { &hf_smb_dir_access_mask_delete_child,
18340           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
18341                 TFS(&flags_set_truth), 0x00000040, "", HFILL }},
18342
18343         { &hf_smb_dir_access_mask_read_attribute,
18344           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
18345                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18346
18347         { &hf_smb_dir_access_mask_write_attribute,
18348           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
18349                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18350
18351         { &hf_smb_unix_file_size,
18352           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18353             NULL, 0, "", HFILL }},
18354
18355         { &hf_smb_unix_file_num_bytes,
18356           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18357             NULL, 0, "Number of bytes used to store the file", HFILL }},
18358
18359         { &hf_smb_unix_file_last_status,
18360           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18361             NULL, 0, "", HFILL }},
18362
18363         { &hf_smb_unix_file_last_access,
18364           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18365             NULL, 0, "", HFILL }},
18366
18367         { &hf_smb_unix_file_last_change,
18368           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18369             NULL, 0, "", HFILL }},
18370
18371         { &hf_smb_unix_file_uid,
18372           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18373             NULL, 0, "", HFILL }},
18374
18375         { &hf_smb_unix_file_gid,
18376           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18377             NULL, 0, "", HFILL }},
18378
18379         { &hf_smb_unix_file_type,
18380           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18381             VALS(unix_file_type_vals), 0, "", HFILL }},
18382
18383         { &hf_smb_unix_file_dev_major,
18384           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18385             NULL, 0, "", HFILL }},
18386
18387         { &hf_smb_unix_file_dev_minor,
18388           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18389             NULL, 0, "", HFILL }},
18390
18391         { &hf_smb_unix_file_unique_id,
18392           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18393             NULL, 0, "", HFILL }},
18394
18395         { &hf_smb_unix_file_permissions,
18396           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18397             NULL, 0, "", HFILL }},
18398
18399         { &hf_smb_unix_file_nlinks,
18400           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18401             NULL, 0, "", HFILL }},
18402
18403         { &hf_smb_unix_file_link_dest,
18404           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
18405             BASE_NONE, NULL, 0, "", HFILL }},
18406
18407         { &hf_smb_unix_find_file_nextoffset,
18408           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18409             NULL, 0, "", HFILL }},
18410
18411         { &hf_smb_unix_find_file_resumekey,
18412           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18413             NULL, 0, "", HFILL }},
18414
18415         { &hf_smb_network_unknown,
18416           { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
18417             NULL, 0, "", HFILL }},
18418
18419         { &hf_smb_create_flags,
18420           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
18421             NULL, 0, "", HFILL }},
18422
18423         { &hf_smb_create_options,
18424           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
18425             NULL, 0, "", HFILL }},
18426
18427         { &hf_smb_share_access,
18428           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
18429             NULL, 0, "", HFILL }},
18430
18431         { &hf_smb_access_mask,
18432           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
18433             NULL, 0, "", HFILL }},
18434
18435         { &hf_smb_mode,
18436           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
18437             NULL, 0, "", HFILL }},
18438
18439         { &hf_smb_attribute,
18440           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
18441             NULL, 0, "", HFILL }},
18442
18443         { &hf_smb_reparse_tag,
18444           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
18445             NULL, 0, "", HFILL }},
18446
18447         { &hf_smb_disposition_delete_on_close,
18448           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
18449                 TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
18450
18451         { &hf_smb_pipe_info_flag,
18452           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
18453                 TFS(&tfs_pipe_info_flag), 0x01, "", HFILL }},
18454
18455         { &hf_smb_logged_in,
18456           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_DEC,
18457                 NULL, 0, "", HFILL }},
18458
18459         { &hf_smb_logged_out,
18460           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_DEC,
18461                 NULL, 0, "", HFILL }},
18462
18463         };
18464
18465         static gint *ett[] = {
18466                 &ett_smb,
18467                 &ett_smb_fid,
18468                 &ett_smb_tid,
18469                 &ett_smb_uid,
18470                 &ett_smb_hdr,
18471                 &ett_smb_command,
18472                 &ett_smb_fileattributes,
18473                 &ett_smb_capabilities,
18474                 &ett_smb_aflags,
18475                 &ett_smb_dialect,
18476                 &ett_smb_dialects,
18477                 &ett_smb_mode,
18478                 &ett_smb_rawmode,
18479                 &ett_smb_flags,
18480                 &ett_smb_flags2,
18481                 &ett_smb_desiredaccess,
18482                 &ett_smb_search,
18483                 &ett_smb_file,
18484                 &ett_smb_openfunction,
18485                 &ett_smb_filetype,
18486                 &ett_smb_openaction,
18487                 &ett_smb_writemode,
18488                 &ett_smb_lock_type,
18489                 &ett_smb_ssetupandxaction,
18490                 &ett_smb_optionsup,
18491                 &ett_smb_time_date,
18492                 &ett_smb_move_copy_flags,
18493                 &ett_smb_file_attributes,
18494                 &ett_smb_search_resume_key,
18495                 &ett_smb_search_dir_info,
18496                 &ett_smb_unlocks,
18497                 &ett_smb_unlock,
18498                 &ett_smb_locks,
18499                 &ett_smb_lock,
18500                 &ett_smb_open_flags,
18501                 &ett_smb_ipc_state,
18502                 &ett_smb_open_action,
18503                 &ett_smb_setup_action,
18504                 &ett_smb_connect_flags,
18505                 &ett_smb_connect_support_bits,
18506                 &ett_smb_nt_access_mask,
18507                 &ett_smb_nt_create_bits,
18508                 &ett_smb_nt_create_options,
18509                 &ett_smb_nt_share_access,
18510                 &ett_smb_nt_security_flags,
18511                 &ett_smb_nt_trans_setup,
18512                 &ett_smb_nt_trans_data,
18513                 &ett_smb_nt_trans_param,
18514                 &ett_smb_nt_notify_completion_filter,
18515                 &ett_smb_nt_ioctl_flags,
18516                 &ett_smb_security_information_mask,
18517                 &ett_smb_print_queue_entry,
18518                 &ett_smb_transaction_flags,
18519                 &ett_smb_transaction_params,
18520                 &ett_smb_find_first2_flags,
18521 #if 0
18522                 &ett_smb_ioflag,
18523 #endif
18524                 &ett_smb_transaction_data,
18525                 &ett_smb_stream_info,
18526                 &ett_smb_dfs_referrals,
18527                 &ett_smb_dfs_referral,
18528                 &ett_smb_dfs_referral_flags,
18529                 &ett_smb_get_dfs_flags,
18530                 &ett_smb_ff2_data,
18531                 &ett_smb_device_characteristics,
18532                 &ett_smb_fs_attributes,
18533                 &ett_smb_segments,
18534                 &ett_smb_segment,
18535                 &ett_smb_quotaflags,
18536                 &ett_smb_secblob,
18537                 &ett_smb_mac_support_flags,
18538                 &ett_smb_unicode_password,
18539                 &ett_smb_ea,
18540                 &ett_smb_unix_capabilities
18541         };
18542         module_t *smb_module;
18543
18544         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
18545             "SMB", "smb");
18546         proto_register_subtree_array(ett, array_length(ett));
18547         proto_register_field_array(proto_smb, hf, array_length(hf));
18548
18549         proto_do_register_windows_common(proto_smb);
18550
18551         register_init_routine(&smb_init_protocol);
18552         smb_module = prefs_register_protocol(proto_smb, NULL);
18553         prefs_register_bool_preference(smb_module, "trans_reassembly",
18554                 "Reassemble SMB Transaction payload",
18555                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
18556                 &smb_trans_reassembly);
18557         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
18558                 "Reassemble DCERPC over SMB",
18559                 "Whether the dissector should reassemble DCERPC over SMB commands",
18560                 &smb_dcerpc_reassembly);
18561         prefs_register_bool_preference(smb_module, "sid_name_snooping",
18562                 "Snoop SID to Name mappings",
18563                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
18564                 &sid_name_snooping);
18565
18566         register_init_routine(smb_trans_reassembly_init);
18567         smb_tap = register_tap("smb");
18568 }
18569
18570 void
18571 proto_reg_handoff_smb(void)
18572 {
18573         dissector_handle_t smb_handle;
18574
18575         gssapi_handle = find_dissector("gssapi");
18576         ntlmssp_handle = find_dissector("ntlmssp");
18577
18578         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
18579         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
18580         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
18581         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
18582         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
18583         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
18584         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
18585             smb_handle);
18586         dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
18587 }