a9cc387d067370a949d4c63f669b18d9e1c73907
[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  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
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/int-64bit.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include "smb.h"
43 #include <epan/strutil.h>
44 #include "prefs.h"
45 #include "reassemble.h"
46 #include "tap.h"
47 #include "packet-ipx.h"
48
49 #include "packet-windows-common.h"
50 #include "packet-smb-common.h"
51 #include "packet-smb-mailslot.h"
52 #include "packet-smb-pipe.h"
53 #include "packet-dcerpc.h"
54 #include "packet-ntlmssp.h"
55
56 /*
57  * Various specifications and documents about SMB can be found in
58  *
59  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
60  *
61  * and a CIFS specification from the Storage Networking Industry Association
62  * can be found on a link from the page at
63  *
64  *      http://www.snia.org/tech_activities/CIFS
65  *
66  * (it supercedes the document at
67  *
68  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
69  *
70  * ).
71  *
72  * There are also some Open Group publications documenting CIFS available
73  * for download; catalog entries for them are at:
74  *
75  *      http://www.opengroup.org/products/publications/catalog/c209.htm
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c195.htm
78  *
79  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
80  * can be found at
81  *
82  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
83  *
84  * (or, presumably a similar path under the Samba mirrors).  As the
85  * ".doc" indicates, it's a Word document.  Some of the specs from the
86  * Microsoft FTP site can be found in the
87  *
88  *      http://www.samba.org/samba/ftp/specs/
89  *
90  * directory as well.
91  *
92  * Beware - these specs may have errors.
93  */
94 static int proto_smb = -1;
95 static int hf_smb_cmd = -1;
96 static int hf_smb_key = -1;
97 static int hf_smb_session_id = -1;
98 static int hf_smb_sequence_num = -1;
99 static int hf_smb_group_id = -1;
100 static int hf_smb_pid = -1;
101 static int hf_smb_tid = -1;
102 static int hf_smb_uid = -1;
103 static int hf_smb_mid = -1;
104 static int hf_smb_pid_high = -1;
105 static int hf_smb_sig = -1;
106 static int hf_smb_response_to = -1;
107 static int hf_smb_time = -1;
108 static int hf_smb_response_in = -1;
109 static int hf_smb_continuation_to = -1;
110 static int hf_smb_nt_status = -1;
111 static int hf_smb_error_class = -1;
112 static int hf_smb_error_code = -1;
113 static int hf_smb_reserved = -1;
114 static int hf_smb_flags_lock = -1;
115 static int hf_smb_flags_receive_buffer = -1;
116 static int hf_smb_flags_caseless = -1;
117 static int hf_smb_flags_canon = -1;
118 static int hf_smb_flags_oplock = -1;
119 static int hf_smb_flags_notify = -1;
120 static int hf_smb_flags_response = -1;
121 static int hf_smb_flags2_long_names_allowed = -1;
122 static int hf_smb_flags2_ea = -1;
123 static int hf_smb_flags2_sec_sig = -1;
124 static int hf_smb_flags2_long_names_used = -1;
125 static int hf_smb_flags2_esn = -1;
126 static int hf_smb_flags2_dfs = -1;
127 static int hf_smb_flags2_roe = -1;
128 static int hf_smb_flags2_nt_error = -1;
129 static int hf_smb_flags2_string = -1;
130 static int hf_smb_word_count = -1;
131 static int hf_smb_byte_count = -1;
132 static int hf_smb_buffer_format = -1;
133 static int hf_smb_dialect_name = -1;
134 static int hf_smb_dialect_index = -1;
135 static int hf_smb_max_trans_buf_size = -1;
136 static int hf_smb_max_mpx_count = -1;
137 static int hf_smb_max_vcs_num = -1;
138 static int hf_smb_session_key = -1;
139 static int hf_smb_server_timezone = -1;
140 static int hf_smb_encryption_key_length = -1;
141 static int hf_smb_encryption_key = -1;
142 static int hf_smb_primary_domain = -1;
143 static int hf_smb_server = -1;
144 static int hf_smb_max_raw_buf_size = -1;
145 static int hf_smb_server_guid = -1;
146 static int hf_smb_security_blob_len = -1;
147 static int hf_smb_security_blob = -1;
148 static int hf_smb_sm_mode16 = -1;
149 static int hf_smb_sm_password16 = -1;
150 static int hf_smb_sm_mode = -1;
151 static int hf_smb_sm_password = -1;
152 static int hf_smb_sm_signatures = -1;
153 static int hf_smb_sm_sig_required = -1;
154 static int hf_smb_rm_read = -1;
155 static int hf_smb_rm_write = -1;
156 static int hf_smb_server_date_time = -1;
157 static int hf_smb_server_smb_date = -1;
158 static int hf_smb_server_smb_time = -1;
159 static int hf_smb_server_cap_raw_mode = -1;
160 static int hf_smb_server_cap_mpx_mode = -1;
161 static int hf_smb_server_cap_unicode = -1;
162 static int hf_smb_server_cap_large_files = -1;
163 static int hf_smb_server_cap_nt_smbs = -1;
164 static int hf_smb_server_cap_rpc_remote_apis = -1;
165 static int hf_smb_server_cap_nt_status = -1;
166 static int hf_smb_server_cap_level_ii_oplocks = -1;
167 static int hf_smb_server_cap_lock_and_read = -1;
168 static int hf_smb_server_cap_nt_find = -1;
169 static int hf_smb_server_cap_dfs = -1;
170 static int hf_smb_server_cap_infolevel_passthru = -1;
171 static int hf_smb_server_cap_large_readx = -1;
172 static int hf_smb_server_cap_large_writex = -1;
173 static int hf_smb_server_cap_unix = -1;
174 static int hf_smb_server_cap_reserved = -1;
175 static int hf_smb_server_cap_bulk_transfer = -1;
176 static int hf_smb_server_cap_compressed_data = -1;
177 static int hf_smb_server_cap_extended_security = -1;
178 static int hf_smb_system_time = -1;
179 static int hf_smb_unknown = -1;
180 static int hf_smb_dir_name = -1;
181 static int hf_smb_echo_count = -1;
182 static int hf_smb_echo_data = -1;
183 static int hf_smb_echo_seq_num = -1;
184 static int hf_smb_max_buf_size = -1;
185 static int hf_smb_password = -1;
186 static int hf_smb_password_len = -1;
187 static int hf_smb_ansi_password = -1;
188 static int hf_smb_ansi_password_len = -1;
189 static int hf_smb_unicode_password = -1;
190 static int hf_smb_unicode_password_len = -1;
191 static int hf_smb_path = -1;
192 static int hf_smb_service = -1;
193 static int hf_smb_move_flags_file = -1;
194 static int hf_smb_move_flags_dir = -1;
195 static int hf_smb_move_flags_verify = -1;
196 static int hf_smb_files_moved = -1;
197 static int hf_smb_copy_flags_file = -1;
198 static int hf_smb_copy_flags_dir = -1;
199 static int hf_smb_copy_flags_dest_mode = -1;
200 static int hf_smb_copy_flags_source_mode = -1;
201 static int hf_smb_copy_flags_verify = -1;
202 static int hf_smb_copy_flags_tree_copy = -1;
203 static int hf_smb_copy_flags_ea_action = -1;
204 static int hf_smb_count = -1;
205 static int hf_smb_count_low = -1;
206 static int hf_smb_count_high = -1;
207 static int hf_smb_file_name = -1;
208 static int hf_smb_open_function_open = -1;
209 static int hf_smb_open_function_create = -1;
210 static int hf_smb_fid = -1;
211 static int hf_smb_file_attr_read_only_16bit = -1;
212 static int hf_smb_file_attr_read_only_8bit = -1;
213 static int hf_smb_file_attr_hidden_16bit = -1;
214 static int hf_smb_file_attr_hidden_8bit = -1;
215 static int hf_smb_file_attr_system_16bit = -1;
216 static int hf_smb_file_attr_system_8bit = -1;
217 static int hf_smb_file_attr_volume_16bit = -1;
218 static int hf_smb_file_attr_volume_8bit = -1;
219 static int hf_smb_file_attr_directory_16bit = -1;
220 static int hf_smb_file_attr_directory_8bit = -1;
221 static int hf_smb_file_attr_archive_16bit = -1;
222 static int hf_smb_file_attr_archive_8bit = -1;
223 static int hf_smb_file_attr_device = -1;
224 static int hf_smb_file_attr_normal = -1;
225 static int hf_smb_file_attr_temporary = -1;
226 static int hf_smb_file_attr_sparse = -1;
227 static int hf_smb_file_attr_reparse = -1;
228 static int hf_smb_file_attr_compressed = -1;
229 static int hf_smb_file_attr_offline = -1;
230 static int hf_smb_file_attr_not_content_indexed = -1;
231 static int hf_smb_file_attr_encrypted = -1;
232 static int hf_smb_file_size = -1;
233 static int hf_smb_search_attribute_read_only = -1;
234 static int hf_smb_search_attribute_hidden = -1;
235 static int hf_smb_search_attribute_system = -1;
236 static int hf_smb_search_attribute_volume = -1;
237 static int hf_smb_search_attribute_directory = -1;
238 static int hf_smb_search_attribute_archive = -1;
239 static int hf_smb_access_mode = -1;
240 static int hf_smb_access_sharing = -1;
241 static int hf_smb_access_locality = -1;
242 static int hf_smb_access_caching = -1;
243 static int hf_smb_access_writetru = -1;
244 static int hf_smb_create_time = -1;
245 static int hf_smb_modify_time = -1;
246 static int hf_smb_backup_time = -1;
247 static int hf_smb_mac_alloc_block_count = -1;
248 static int hf_smb_mac_alloc_block_size = -1;
249 static int hf_smb_mac_free_block_count = -1;
250 static int hf_smb_mac_fndrinfo = -1;
251 static int hf_smb_mac_root_file_count = -1;
252 static int hf_smb_mac_root_dir_count = -1;
253 static int hf_smb_mac_file_count = -1;
254 static int hf_smb_mac_dir_count = -1;
255 static int hf_smb_mac_support_flags = -1;
256 static int hf_smb_mac_sup_access_ctrl = -1;
257 static int hf_smb_mac_sup_getset_comments = -1;
258 static int hf_smb_mac_sup_desktopdb_calls = -1;
259 static int hf_smb_mac_sup_unique_ids = -1;
260 static int hf_smb_mac_sup_streams = -1;
261 static int hf_smb_create_dos_date = -1;
262 static int hf_smb_create_dos_time = -1;
263 static int hf_smb_last_write_time = -1;
264 static int hf_smb_last_write_dos_date = -1;
265 static int hf_smb_last_write_dos_time = -1;
266 static int hf_smb_access_time = -1;
267 static int hf_smb_access_dos_date = -1;
268 static int hf_smb_access_dos_time = -1;
269 static int hf_smb_old_file_name = -1;
270 static int hf_smb_offset = -1;
271 static int hf_smb_remaining = -1;
272 static int hf_smb_padding = -1;
273 static int hf_smb_file_data = -1;
274 static int hf_smb_total_data_len = -1;
275 static int hf_smb_data_len = -1;
276 static int hf_smb_data_len_low = -1;
277 static int hf_smb_data_len_high = -1;
278 static int hf_smb_seek_mode = -1;
279 static int hf_smb_data_size = -1;
280 static int hf_smb_alloc_size = -1;
281 static int hf_smb_alloc_size64 = -1;
282 static int hf_smb_max_count = -1;
283 static int hf_smb_max_count_low = -1;
284 static int hf_smb_max_count_high = -1;
285 static int hf_smb_min_count = -1;
286 static int hf_smb_timeout = -1;
287 static int hf_smb_high_offset = -1;
288 static int hf_smb_units = -1;
289 static int hf_smb_bpu = -1;
290 static int hf_smb_blocksize = -1;
291 static int hf_smb_freeunits = -1;
292 static int hf_smb_data_offset = -1;
293 static int hf_smb_dcm = -1;
294 static int hf_smb_request_mask = -1;
295 static int hf_smb_response_mask = -1;
296 static int hf_smb_search_id = -1;
297 static int hf_smb_write_mode_write_through = -1;
298 static int hf_smb_write_mode_return_remaining = -1;
299 static int hf_smb_write_mode_raw = -1;
300 static int hf_smb_write_mode_message_start = -1;
301 static int hf_smb_write_mode_connectionless = -1;
302 static int hf_smb_resume_key_len = -1;
303 static int hf_smb_resume_find_id = -1;
304 static int hf_smb_resume_server_cookie = -1;
305 static int hf_smb_resume_client_cookie = -1;
306 static int hf_smb_andxoffset = -1;
307 static int hf_smb_lock_type_large = -1;
308 static int hf_smb_lock_type_cancel = -1;
309 static int hf_smb_lock_type_change = -1;
310 static int hf_smb_lock_type_oplock = -1;
311 static int hf_smb_lock_type_shared = -1;
312 static int hf_smb_locking_ol = -1;
313 static int hf_smb_number_of_locks = -1;
314 static int hf_smb_number_of_unlocks = -1;
315 static int hf_smb_lock_long_offset = -1;
316 static int hf_smb_lock_long_length = -1;
317 static int hf_smb_file_type = -1;
318 static int hf_smb_ipc_state_nonblocking = -1;
319 static int hf_smb_ipc_state_endpoint = -1;
320 static int hf_smb_ipc_state_pipe_type = -1;
321 static int hf_smb_ipc_state_read_mode = -1;
322 static int hf_smb_ipc_state_icount = -1;
323 static int hf_smb_server_fid = -1;
324 static int hf_smb_open_flags_add_info = -1;
325 static int hf_smb_open_flags_ex_oplock = -1;
326 static int hf_smb_open_flags_batch_oplock = -1;
327 static int hf_smb_open_flags_ealen = -1;
328 static int hf_smb_open_action_open = -1;
329 static int hf_smb_open_action_lock = -1;
330 static int hf_smb_vc_num = -1;
331 static int hf_smb_account = -1;
332 static int hf_smb_os = -1;
333 static int hf_smb_lanman = -1;
334 static int hf_smb_setup_action_guest = -1;
335 static int hf_smb_fs = -1;
336 static int hf_smb_connect_flags_dtid = -1;
337 static int hf_smb_connect_support_search = -1;
338 static int hf_smb_connect_support_in_dfs = -1;
339 static int hf_smb_max_setup_count = -1;
340 static int hf_smb_total_param_count = -1;
341 static int hf_smb_total_data_count = -1;
342 static int hf_smb_max_param_count = -1;
343 static int hf_smb_max_data_count = -1;
344 static int hf_smb_param_disp16 = -1;
345 static int hf_smb_param_count16 = -1;
346 static int hf_smb_param_offset16 = -1;
347 static int hf_smb_param_disp32 = -1;
348 static int hf_smb_param_count32 = -1;
349 static int hf_smb_param_offset32 = -1;
350 static int hf_smb_data_disp16 = -1;
351 static int hf_smb_data_count16 = -1;
352 static int hf_smb_data_offset16 = -1;
353 static int hf_smb_data_disp32 = -1;
354 static int hf_smb_data_count32 = -1;
355 static int hf_smb_data_offset32 = -1;
356 static int hf_smb_setup_count = -1;
357 static int hf_smb_nt_trans_subcmd = -1;
358 static int hf_smb_nt_ioctl_function_code = -1;
359 static int hf_smb_nt_ioctl_isfsctl = -1;
360 static int hf_smb_nt_ioctl_flags_root_handle = -1;
361 static int hf_smb_nt_ioctl_data = -1;
362 #ifdef SMB_UNUSED_HANDLES
363 static int hf_smb_nt_security_information = -1;
364 #endif
365 static int hf_smb_nt_notify_action = -1;
366 static int hf_smb_nt_notify_watch_tree = -1;
367 static int hf_smb_nt_notify_stream_write = -1;
368 static int hf_smb_nt_notify_stream_size = -1;
369 static int hf_smb_nt_notify_stream_name = -1;
370 static int hf_smb_nt_notify_security = -1;
371 static int hf_smb_nt_notify_ea = -1;
372 static int hf_smb_nt_notify_creation = -1;
373 static int hf_smb_nt_notify_last_access = -1;
374 static int hf_smb_nt_notify_last_write = -1;
375 static int hf_smb_nt_notify_size = -1;
376 static int hf_smb_nt_notify_attributes = -1;
377 static int hf_smb_nt_notify_dir_name = -1;
378 static int hf_smb_nt_notify_file_name = -1;
379 static int hf_smb_root_dir_fid = -1;
380 static int hf_smb_nt_create_disposition = -1;
381 static int hf_smb_sd_length = -1;
382 static int hf_smb_ea_list_length = -1;
383 static int hf_smb_ea_flags = -1;
384 static int hf_smb_ea_name_length = -1;
385 static int hf_smb_ea_data_length = -1;
386 static int hf_smb_ea_name = -1;
387 static int hf_smb_ea_data = -1;
388 static int hf_smb_file_name_len = -1;
389 static int hf_smb_nt_impersonation_level = -1;
390 static int hf_smb_nt_security_flags_context_tracking = -1;
391 static int hf_smb_nt_security_flags_effective_only = -1;
392 static int hf_smb_nt_access_mask_generic_read = -1;
393 static int hf_smb_nt_access_mask_generic_write = -1;
394 static int hf_smb_nt_access_mask_generic_execute = -1;
395 static int hf_smb_nt_access_mask_generic_all = -1;
396 static int hf_smb_nt_access_mask_maximum_allowed = -1;
397 static int hf_smb_nt_access_mask_system_security = -1;
398 static int hf_smb_nt_access_mask_synchronize = -1;
399 static int hf_smb_nt_access_mask_write_owner = -1;
400 static int hf_smb_nt_access_mask_write_dac = -1;
401 static int hf_smb_nt_access_mask_read_control = -1;
402 static int hf_smb_nt_access_mask_delete = -1;
403 static int hf_smb_nt_access_mask_write_attributes = -1;
404 static int hf_smb_nt_access_mask_read_attributes = -1;
405 static int hf_smb_nt_access_mask_delete_child = -1;
406 static int hf_smb_nt_access_mask_execute = -1;
407 static int hf_smb_nt_access_mask_write_ea = -1;
408 static int hf_smb_nt_access_mask_read_ea = -1;
409 static int hf_smb_nt_access_mask_append = -1;
410 static int hf_smb_nt_access_mask_write = -1;
411 static int hf_smb_nt_access_mask_read = -1;
412 static int hf_smb_nt_create_bits_oplock = -1;
413 static int hf_smb_nt_create_bits_boplock = -1;
414 static int hf_smb_nt_create_bits_dir = -1;
415 static int hf_smb_nt_create_bits_ext_resp = -1;
416 static int hf_smb_nt_create_options_directory_file = -1;
417 static int hf_smb_nt_create_options_write_through = -1;
418 static int hf_smb_nt_create_options_sequential_only = -1;
419 static int hf_smb_nt_create_options_sync_io_alert = -1;
420 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
421 static int hf_smb_nt_create_options_non_directory_file = -1;
422 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
423 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
424 static int hf_smb_nt_create_options_random_access = -1;
425 static int hf_smb_nt_create_options_delete_on_close = -1;
426 static int hf_smb_nt_share_access_read = -1;
427 static int hf_smb_nt_share_access_write = -1;
428 static int hf_smb_nt_share_access_delete = -1;
429 static int hf_smb_file_eattr_read_only = -1;
430 static int hf_smb_file_eattr_hidden = -1;
431 static int hf_smb_file_eattr_system = -1;
432 static int hf_smb_file_eattr_volume = -1;
433 static int hf_smb_file_eattr_directory = -1;
434 static int hf_smb_file_eattr_archive = -1;
435 static int hf_smb_file_eattr_device = -1;
436 static int hf_smb_file_eattr_normal = -1;
437 static int hf_smb_file_eattr_temporary = -1;
438 static int hf_smb_file_eattr_sparse = -1;
439 static int hf_smb_file_eattr_reparse = -1;
440 static int hf_smb_file_eattr_compressed = -1;
441 static int hf_smb_file_eattr_offline = -1;
442 static int hf_smb_file_eattr_not_content_indexed = -1;
443 static int hf_smb_file_eattr_encrypted = -1;
444 static int hf_smb_sec_desc_len = -1;
445 static int hf_smb_nt_qsd_owner = -1;
446 static int hf_smb_nt_qsd_group = -1;
447 static int hf_smb_nt_qsd_dacl = -1;
448 static int hf_smb_nt_qsd_sacl = -1;
449 static int hf_smb_extended_attributes = -1;
450 static int hf_smb_oplock_level = -1;
451 static int hf_smb_create_action = -1;
452 static int hf_smb_file_id = -1;
453 static int hf_smb_ea_error_offset = -1;
454 static int hf_smb_end_of_file = -1;
455 static int hf_smb_replace = -1;
456 static int hf_smb_root_dir_handle = -1;
457 static int hf_smb_target_name_len = -1;
458 static int hf_smb_target_name = -1;
459 static int hf_smb_device_type = -1;
460 static int hf_smb_is_directory = -1;
461 static int hf_smb_next_entry_offset = -1;
462 static int hf_smb_change_time = -1;
463 static int hf_smb_setup_len = -1;
464 static int hf_smb_print_mode = -1;
465 static int hf_smb_print_identifier = -1;
466 static int hf_smb_restart_index = -1;
467 static int hf_smb_print_queue_date = -1;
468 static int hf_smb_print_queue_dos_date = -1;
469 static int hf_smb_print_queue_dos_time = -1;
470 static int hf_smb_print_status = -1;
471 static int hf_smb_print_spool_file_number = -1;
472 static int hf_smb_print_spool_file_size = -1;
473 static int hf_smb_print_spool_file_name = -1;
474 static int hf_smb_start_index = -1;
475 static int hf_smb_originator_name = -1;
476 static int hf_smb_destination_name = -1;
477 static int hf_smb_message_len = -1;
478 static int hf_smb_message = -1;
479 static int hf_smb_mgid = -1;
480 static int hf_smb_forwarded_name = -1;
481 static int hf_smb_machine_name = -1;
482 static int hf_smb_cancel_to = -1;
483 static int hf_smb_trans2_subcmd = -1;
484 static int hf_smb_trans_name = -1;
485 static int hf_smb_transaction_flags_dtid = -1;
486 static int hf_smb_transaction_flags_owt = -1;
487 static int hf_smb_search_count = -1;
488 static int hf_smb_search_pattern = -1;
489 static int hf_smb_ff2_backup = -1;
490 static int hf_smb_ff2_continue = -1;
491 static int hf_smb_ff2_resume = -1;
492 static int hf_smb_ff2_close_eos = -1;
493 static int hf_smb_ff2_close = -1;
494 static int hf_smb_ff2_information_level = -1;
495 static int hf_smb_qpi_loi = -1;
496 static int hf_smb_spi_loi = -1;
497 #if 0
498 static int hf_smb_sfi_writetru = -1;
499 static int hf_smb_sfi_caching = -1;
500 #endif
501 static int hf_smb_storage_type = -1;
502 static int hf_smb_resume = -1;
503 static int hf_smb_max_referral_level = -1;
504 static int hf_smb_qfsi_information_level = -1;
505 static int hf_smb_number_of_links = -1;
506 static int hf_smb_delete_pending = -1;
507 static int hf_smb_index_number = -1;
508 static int hf_smb_current_offset = -1;
509 static int hf_smb_t2_alignment = -1;
510 static int hf_smb_t2_stream_name_length = -1;
511 static int hf_smb_t2_stream_size = -1;
512 static int hf_smb_t2_stream_name = -1;
513 static int hf_smb_t2_compressed_file_size = -1;
514 static int hf_smb_t2_compressed_format = -1;
515 static int hf_smb_t2_compressed_unit_shift = -1;
516 static int hf_smb_t2_compressed_chunk_shift = -1;
517 static int hf_smb_t2_compressed_cluster_shift = -1;
518 static int hf_smb_t2_marked_for_deletion = -1;
519 static int hf_smb_dfs_path_consumed = -1;
520 static int hf_smb_dfs_num_referrals = -1;
521 static int hf_smb_get_dfs_server_hold_storage = -1;
522 static int hf_smb_get_dfs_fielding = -1;
523 static int hf_smb_dfs_referral_version = -1;
524 static int hf_smb_dfs_referral_size = -1;
525 static int hf_smb_dfs_referral_server_type = -1;
526 static int hf_smb_dfs_referral_flags_strip = -1;
527 static int hf_smb_dfs_referral_node_offset = -1;
528 static int hf_smb_dfs_referral_node = -1;
529 static int hf_smb_dfs_referral_proximity = -1;
530 static int hf_smb_dfs_referral_ttl = -1;
531 static int hf_smb_dfs_referral_path_offset = -1;
532 static int hf_smb_dfs_referral_path = -1;
533 static int hf_smb_dfs_referral_alt_path_offset = -1;
534 static int hf_smb_dfs_referral_alt_path = -1;
535 static int hf_smb_end_of_search = -1;
536 static int hf_smb_last_name_offset = -1;
537 static int hf_smb_fn_information_level = -1;
538 static int hf_smb_monitor_handle = -1;
539 static int hf_smb_change_count = -1;
540 static int hf_smb_file_index = -1;
541 static int hf_smb_short_file_name = -1;
542 static int hf_smb_short_file_name_len = -1;
543 static int hf_smb_fs_id = -1;
544 static int hf_smb_fs_guid = -1;
545 static int hf_smb_sector_unit = -1;
546 static int hf_smb_fs_units = -1;
547 static int hf_smb_fs_sector = -1;
548 static int hf_smb_avail_units = -1;
549 static int hf_smb_volume_serial_num = -1;
550 static int hf_smb_volume_label_len = -1;
551 static int hf_smb_volume_label = -1;
552 static int hf_smb_free_alloc_units64 = -1;
553 static int hf_smb_caller_free_alloc_units64 = -1;
554 static int hf_smb_actual_free_alloc_units64 = -1;
555 static int hf_smb_max_name_len = -1;
556 static int hf_smb_fs_name_len = -1;
557 static int hf_smb_fs_name = -1;
558 static int hf_smb_device_char_removable = -1;
559 static int hf_smb_device_char_read_only = -1;
560 static int hf_smb_device_char_floppy = -1;
561 static int hf_smb_device_char_write_once = -1;
562 static int hf_smb_device_char_remote = -1;
563 static int hf_smb_device_char_mounted = -1;
564 static int hf_smb_device_char_virtual = -1;
565 static int hf_smb_fs_attr_css = -1;
566 static int hf_smb_fs_attr_cpn = -1;
567 static int hf_smb_fs_attr_uod = -1;
568 static int hf_smb_fs_attr_pacls = -1;
569 static int hf_smb_fs_attr_fc = -1;
570 static int hf_smb_fs_attr_vq = -1;
571 static int hf_smb_fs_attr_ssf = -1;
572 static int hf_smb_fs_attr_srp = -1;
573 static int hf_smb_fs_attr_srs = -1;
574 static int hf_smb_fs_attr_sla = -1;
575 static int hf_smb_fs_attr_vic = -1;
576 static int hf_smb_fs_attr_soids = -1;
577 static int hf_smb_fs_attr_se = -1;
578 static int hf_smb_fs_attr_ns = -1;
579 static int hf_smb_fs_attr_rov = -1;
580 static int hf_smb_quota_flags_enabled = -1;
581 static int hf_smb_quota_flags_deny_disk = -1;
582 static int hf_smb_quota_flags_log_limit = -1;
583 static int hf_smb_quota_flags_log_warning = -1;
584 static int hf_smb_soft_quota_limit = -1;
585 static int hf_smb_hard_quota_limit = -1;
586 static int hf_smb_user_quota_used = -1;
587 static int hf_smb_user_quota_offset = -1;
588 static int hf_smb_nt_rename_level = -1;
589 static int hf_smb_cluster_count = -1;
590 static int hf_smb_segments = -1;
591 static int hf_smb_segment = -1;
592 static int hf_smb_segment_overlap = -1;
593 static int hf_smb_segment_overlap_conflict = -1;
594 static int hf_smb_segment_multiple_tails = -1;
595 static int hf_smb_segment_too_long_fragment = -1;
596 static int hf_smb_segment_error = -1;
597 static int hf_smb_pipe_write_len = -1;
598 static int hf_smb_unix_major_version = -1;
599 static int hf_smb_unix_minor_version = -1;
600 static int hf_smb_unix_capability_fcntl = -1;
601 static int hf_smb_unix_capability_posix_acl = -1;
602 static int hf_smb_unix_file_size = -1;
603 static int hf_smb_unix_file_num_bytes = -1;
604 static int hf_smb_unix_file_last_status = -1;
605 static int hf_smb_unix_file_last_access = -1;
606 static int hf_smb_unix_file_last_change = -1;
607 static int hf_smb_unix_file_uid = -1;
608 static int hf_smb_unix_file_gid = -1;
609 static int hf_smb_unix_file_type = -1;
610 static int hf_smb_unix_file_dev_major = -1;
611 static int hf_smb_unix_file_dev_minor = -1;
612 static int hf_smb_unix_file_unique_id = -1;
613 static int hf_smb_unix_file_permissions = -1;
614 static int hf_smb_unix_file_nlinks = -1;
615 static int hf_smb_unix_file_link_dest = -1;
616 static int hf_smb_unix_find_file_nextoffset = -1;
617 static int hf_smb_unix_find_file_resumekey = -1;
618
619 static gint ett_smb = -1;
620 static gint ett_smb_hdr = -1;
621 static gint ett_smb_command = -1;
622 static gint ett_smb_fileattributes = -1;
623 static gint ett_smb_capabilities = -1;
624 static gint ett_smb_aflags = -1;
625 static gint ett_smb_dialect = -1;
626 static gint ett_smb_dialects = -1;
627 static gint ett_smb_mode = -1;
628 static gint ett_smb_rawmode = -1;
629 static gint ett_smb_flags = -1;
630 static gint ett_smb_flags2 = -1;
631 static gint ett_smb_desiredaccess = -1;
632 static gint ett_smb_search = -1;
633 static gint ett_smb_file = -1;
634 static gint ett_smb_openfunction = -1;
635 static gint ett_smb_filetype = -1;
636 static gint ett_smb_openaction = -1;
637 static gint ett_smb_writemode = -1;
638 static gint ett_smb_lock_type = -1;
639 static gint ett_smb_ssetupandxaction = -1;
640 static gint ett_smb_optionsup = -1;
641 static gint ett_smb_time_date = -1;
642 static gint ett_smb_move_copy_flags = -1;
643 static gint ett_smb_file_attributes = -1;
644 static gint ett_smb_search_resume_key = -1;
645 static gint ett_smb_search_dir_info = -1;
646 static gint ett_smb_unlocks = -1;
647 static gint ett_smb_unlock = -1;
648 static gint ett_smb_locks = -1;
649 static gint ett_smb_lock = -1;
650 static gint ett_smb_open_flags = -1;
651 static gint ett_smb_ipc_state = -1;
652 static gint ett_smb_open_action = -1;
653 static gint ett_smb_setup_action = -1;
654 static gint ett_smb_connect_flags = -1;
655 static gint ett_smb_connect_support_bits = -1;
656 static gint ett_smb_nt_access_mask = -1;
657 static gint ett_smb_nt_create_bits = -1;
658 static gint ett_smb_nt_create_options = -1;
659 static gint ett_smb_nt_share_access = -1;
660 static gint ett_smb_nt_security_flags = -1;
661 static gint ett_smb_nt_trans_setup = -1;
662 static gint ett_smb_nt_trans_data = -1;
663 static gint ett_smb_nt_trans_param = -1;
664 static gint ett_smb_nt_notify_completion_filter = -1;
665 static gint ett_smb_nt_ioctl_flags = -1;
666 static gint ett_smb_security_information_mask = -1;
667 static gint ett_smb_print_queue_entry = -1;
668 static gint ett_smb_transaction_flags = -1;
669 static gint ett_smb_transaction_params = -1;
670 static gint ett_smb_find_first2_flags = -1;
671 static gint ett_smb_mac_support_flags = -1;
672 #if 0
673 static gint ett_smb_ioflag = -1;
674 #endif
675 static gint ett_smb_transaction_data = -1;
676 static gint ett_smb_stream_info = -1;
677 static gint ett_smb_dfs_referrals = -1;
678 static gint ett_smb_dfs_referral = -1;
679 static gint ett_smb_dfs_referral_flags = -1;
680 static gint ett_smb_get_dfs_flags = -1;
681 static gint ett_smb_ff2_data = -1;
682 static gint ett_smb_device_characteristics = -1;
683 static gint ett_smb_fs_attributes = -1;
684 static gint ett_smb_segments = -1;
685 static gint ett_smb_segment = -1;
686 static gint ett_smb_quotaflags = -1;
687 static gint ett_smb_secblob = -1;
688 static gint ett_smb_unicode_password = -1;
689 static gint ett_smb_ea = -1;
690 static gint ett_smb_unix_capabilities = -1;
691
692 static int smb_tap = -1;
693
694 static dissector_handle_t gssapi_handle = NULL;
695 static dissector_handle_t ntlmssp_handle = NULL;
696
697 static const fragment_items smb_frag_items = {
698         &ett_smb_segment,
699         &ett_smb_segments,
700
701         &hf_smb_segments,
702         &hf_smb_segment,
703         &hf_smb_segment_overlap,
704         &hf_smb_segment_overlap_conflict,
705         &hf_smb_segment_multiple_tails,
706         &hf_smb_segment_too_long_fragment,
707         &hf_smb_segment_error,
708         NULL,
709
710         "segments"
711 };
712
713 proto_tree *top_tree=NULL;     /* ugly */
714
715 static char *decode_smb_name(guint8);
716 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
717
718 /*
719  * Macros for use in the main dissector routines for an SMB.
720  */
721
722 #define WORD_COUNT      \
723         /* Word Count */                                \
724         wc = tvb_get_guint8(tvb, offset);               \
725         proto_tree_add_uint(tree, hf_smb_word_count,    \
726                 tvb, offset, 1, wc);                    \
727         offset += 1;                                    \
728         if(wc==0) goto bytecount;
729
730 #define BYTE_COUNT      \
731         bytecount:                                      \
732         bc = tvb_get_letohs(tvb, offset);               \
733         proto_tree_add_uint(tree, hf_smb_byte_count,    \
734                         tvb, offset, 2, bc);            \
735         offset += 2;                                    \
736         if(bc==0) goto endofcommand;
737
738 #define CHECK_BYTE_COUNT(len)   \
739         if (bc < len) goto endofcommand;
740
741 #define COUNT_BYTES(len)   {\
742         int tmp;            \
743         tmp=len;            \
744         offset += tmp;      \
745         bc -= tmp;          \
746         }
747
748 #define END_OF_SMB      \
749         if (bc != 0) { \
750                 gint bc_remaining; \
751                 bc_remaining=tvb_length_remaining(tvb, offset); \
752                 if( ((gint)bc) > bc_remaining){ \
753                         bc=bc_remaining; \
754                 } \
755                 if(bc){ \
756                         proto_tree_add_text(tree, tvb, offset, bc, \
757                             "Extra byte parameters");           \
758                 } \
759                 offset += bc;                           \
760         }                                               \
761         endofcommand:
762
763 /*
764  * Macros for use in routines called by them.
765  */
766 #define CHECK_BYTE_COUNT_SUBR(len)      \
767         if (*bcp < len) {               \
768                 *trunc = TRUE;          \
769                 return offset;          \
770         }
771
772 #define CHECK_STRING_SUBR(fn)   \
773         if (fn == NULL) {       \
774                 *trunc = TRUE;  \
775                 return offset;  \
776         }
777
778 #define COUNT_BYTES_SUBR(len)   \
779         offset += len;          \
780         *bcp -= len;
781
782 /*
783  * Macros for use when dissecting transaction parameters and data
784  */
785 #define CHECK_BYTE_COUNT_TRANS(len)     \
786         if (bc < len) return offset;
787
788 #define CHECK_STRING_TRANS(fn)  \
789         if (fn == NULL) return offset;
790
791 #define COUNT_BYTES_TRANS(len)  \
792         offset += len;          \
793         bc -= len;
794
795 /*
796  * Macros for use in subrroutines dissecting transaction parameters or data
797  */
798 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
799         if (*bcp < len) return offset;
800
801 #define CHECK_STRING_TRANS_SUBR(fn)     \
802         if (fn == NULL) return offset;
803
804 #define COUNT_BYTES_TRANS_SUBR(len)     \
805         offset += len;                  \
806         *bcp -= len;
807
808
809 gboolean sid_name_snooping = FALSE;
810
811 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
812    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
813    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
814 static gboolean smb_trans_reassembly = FALSE;
815 gboolean smb_dcerpc_reassembly = FALSE;
816
817 static GHashTable *smb_trans_fragment_table = NULL;
818
819 static void
820 smb_trans_reassembly_init(void)
821 {
822         fragment_table_init(&smb_trans_fragment_table);
823 }
824
825 static fragment_data *
826 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
827                      int offset, int count, int pos, int totlen)
828 {
829         fragment_data *fd_head=NULL;
830         smb_info_t *si;
831         int more_frags;
832
833         more_frags=totlen>(pos+count);
834
835         si = (smb_info_t *)pinfo->private_data;
836         if (si->sip == NULL) {
837                 /*
838                  * We don't have the frame number of the request.
839                  *
840                  * XXX - is there truly nothing we can do here?
841                  * Can we not separately keep track of the original
842                  * transaction and its continuations, as we did
843                  * at one time?
844                  *
845                  * It is probably not much point in even trying to do something here
846                  * if we have never seen the initial request. Without the initial
847                  * request we probably miss all parameters and the begining of data
848                  * so we cant even call a subdissector since we can not determine
849                  * which type of transaction call this is.
850                  */
851                 return NULL;
852         }
853
854         if(!pinfo->fd->flags.visited){
855                 fd_head = fragment_add(tvb, offset, pinfo,
856                                        si->sip->frame_req, smb_trans_fragment_table,
857                                        pos, count, more_frags);
858         } else {
859                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
860         }
861
862         /* we only show the defragmented packet for the first fragment,
863            or else we might end up with dissecting one HUGE transaction PDU
864            a LOT of times. (first fragment is the only one containing the setup
865            bytes)
866            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
867            SMBs. Takes a LOT of time dissecting and is not fun.
868         */
869         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
870                 return fd_head;
871         } else {
872                 return NULL;
873         }
874 }
875
876
877
878
879
880 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
881    These variables and functions are used to match
882    responses with calls
883    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
884 /*
885  * The information we need to save about a request in order to show the
886  * frame number of the request in the dissection of the reply.
887  */
888 typedef struct  {
889         guint32 frame;
890         guint32 pid_mid;
891 } smb_saved_info_key_t;
892
893 static GMemChunk *smb_saved_info_key_chunk = NULL;
894 static GMemChunk *smb_saved_info_chunk = NULL;
895 static int smb_saved_info_init_count = 200;
896
897 /* unmatched smb_saved_info structures.
898    For unmatched smb_saved_info structures we store the smb_saved_info
899    structure using the MID and the PID as the key.
900
901    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
902    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
903    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
904 */
905 static gint
906 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
907 {
908         register guint32 key1 = (guint32)k1;
909         register guint32 key2 = (guint32)k2;
910         return key1==key2;
911 }
912 static guint
913 smb_saved_info_hash_unmatched(gconstpointer k)
914 {
915         register guint32 key = (guint32)k;
916         return key;
917 }
918
919 /* matched smb_saved_info structures.
920    For matched smb_saved_info structures we store the smb_saved_info
921    structure twice in the table using the frame number, and a combination
922    of the MID and the PID, as the key.
923    The frame number is guaranteed to be unique but if ever someone makes
924    some change that will renumber the frames in a capture we are in BIG trouble.
925    This is not likely though since that would break (among other things) all the
926    reassembly routines as well.
927
928    We also need the MID as there may be more than one SMB request or reply
929    in a single frame, and we also need the PID as there may be more than
930    one outstanding request with the same MID and different PIDs.
931 */
932 static gint
933 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
934 {
935         const smb_saved_info_key_t *key1 = k1;
936         const smb_saved_info_key_t *key2 = k2;
937         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
938 }
939 static guint
940 smb_saved_info_hash_matched(gconstpointer k)
941 {
942         const smb_saved_info_key_t *key = k;
943         return key->frame + key->pid_mid;
944 }
945
946 static GMemChunk *smb_nt_transact_info_chunk = NULL;
947 static int smb_nt_transact_info_init_count = 200;
948
949 static GMemChunk *smb_transact2_info_chunk = NULL;
950 static int smb_transact2_info_init_count = 200;
951
952 /*
953  * The information we need to save about a Transaction request in order
954  * to dissect the reply; this includes information for use by the
955  * Remote API dissector.
956  */
957 static GMemChunk *smb_transact_info_chunk = NULL;
958 static int smb_transact_info_init_count = 200;
959
960 static GMemChunk *conv_tables_chunk = NULL;
961 static GSList *conv_tables = NULL;
962 static int conv_tables_count = 10;
963
964
965 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
966    End of request/response matching functions
967    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
968
969 static const value_string buffer_format_vals[] = {
970         {1,     "Data Block"},
971         {2,     "Dialect"},
972         {3,     "Pathname"},
973         {4,     "ASCII"},
974         {5,     "Variable Block"},
975         {0,     NULL}
976 };
977
978 /*
979  * UTIME - this is *almost* like a UNIX time stamp, except that it's
980  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
981  * January 1, 1970, 00:00:00 GMT.
982  *
983  * This means we have to do some extra work to convert it.  This code is
984  * based on the Samba code:
985  *
986  *      Unix SMB/Netbios implementation.
987  *      Version 1.9.
988  *      time handling functions
989  *      Copyright (C) Andrew Tridgell 1992-1998
990  */
991
992 /*
993  * Yield the difference between *A and *B, in seconds, ignoring leap
994  * seconds.
995  */
996 #define TM_YEAR_BASE 1900
997
998 static int
999 tm_diff(struct tm *a, struct tm *b)
1000 {
1001         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1002         int by = b->tm_year + (TM_YEAR_BASE - 1);
1003         int intervening_leap_days =
1004             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1005         int years = ay - by;
1006         int days =
1007             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1008         int hours = 24*days + (a->tm_hour - b->tm_hour);
1009         int minutes = 60*hours + (a->tm_min - b->tm_min);
1010         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1011
1012         return seconds;
1013 }
1014
1015 /*
1016  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1017  * determined.
1018  */
1019 static int
1020 TimeZone(time_t t)
1021 {
1022         struct tm *tm = gmtime(&t);
1023         struct tm tm_utc;
1024
1025         if (tm == NULL)
1026                 return 0;
1027         tm_utc = *tm;
1028         tm = localtime(&t);
1029         if (tm == NULL)
1030                 return 0;
1031         return tm_diff(&tm_utc,tm);
1032 }
1033
1034 /*
1035  * Return the same value as TimeZone, but it should be more efficient.
1036  *
1037  * We keep a table of DST offsets to prevent calling localtime() on each
1038  * call of this function. This saves a LOT of time on many unixes.
1039  *
1040  * Updated by Paul Eggert <eggert@twinsun.com>
1041  */
1042 #ifndef CHAR_BIT
1043 #define CHAR_BIT 8
1044 #endif
1045
1046 #ifndef TIME_T_MIN
1047 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1048                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1049 #endif
1050 #ifndef TIME_T_MAX
1051 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1052 #endif
1053
1054 static int
1055 TimeZoneFaster(time_t t)
1056 {
1057         static struct dst_table {time_t start,end; int zone;} *tdt;
1058         static struct dst_table *dst_table = NULL;
1059         static int table_size = 0;
1060         int i;
1061         int zone = 0;
1062
1063         if (t == 0)
1064                 t = time(NULL);
1065
1066         /* Tunis has a 8 day DST region, we need to be careful ... */
1067 #define MAX_DST_WIDTH (365*24*60*60)
1068 #define MAX_DST_SKIP (7*24*60*60)
1069
1070         for (i = 0; i < table_size; i++) {
1071                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1072                         break;
1073         }
1074
1075         if (i < table_size) {
1076                 zone = dst_table[i].zone;
1077         } else {
1078                 time_t low,high;
1079
1080                 zone = TimeZone(t);
1081                 if (dst_table == NULL)
1082                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1083                 else
1084                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1085                 if (tdt == NULL) {
1086                         if (dst_table)
1087                                 g_free(dst_table);
1088                         table_size = 0;
1089                 } else {
1090                         dst_table = tdt;
1091                         table_size++;
1092
1093                         dst_table[i].zone = zone;
1094                         dst_table[i].start = dst_table[i].end = t;
1095
1096                         /* no entry will cover more than 6 months */
1097                         low = t - MAX_DST_WIDTH/2;
1098                         if (t < low)
1099                                 low = TIME_T_MIN;
1100
1101                         high = t + MAX_DST_WIDTH/2;
1102                         if (high < t)
1103                                 high = TIME_T_MAX;
1104
1105                         /*
1106                          * Widen the new entry using two bisection searches.
1107                          */
1108                         while (low+60*60 < dst_table[i].start) {
1109                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1110                                         t = dst_table[i].start - MAX_DST_SKIP;
1111                                 else
1112                                         t = low + (dst_table[i].start-low)/2;
1113                                 if (TimeZone(t) == zone)
1114                                         dst_table[i].start = t;
1115                                 else
1116                                         low = t;
1117                         }
1118
1119                         while (high-60*60 > dst_table[i].end) {
1120                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1121                                         t = dst_table[i].end + MAX_DST_SKIP;
1122                                 else
1123                                         t = high - (high-dst_table[i].end)/2;
1124                                 if (TimeZone(t) == zone)
1125                                         dst_table[i].end = t;
1126                                 else
1127                                         high = t;
1128                         }
1129                 }
1130         }
1131         return zone;
1132 }
1133
1134 /*
1135  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1136  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1137  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1138  * daylight savings transitions because some local times are ambiguous.
1139  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1140  */
1141 static int
1142 LocTimeDiff(time_t lt)
1143 {
1144         int d = TimeZoneFaster(lt);
1145         time_t t = lt + d;
1146
1147         /* if overflow occurred, ignore all the adjustments so far */
1148         if (((t < lt) ^ (d < 0)))
1149                 t = lt;
1150
1151         /*
1152          * Now t should be close enough to the true UTC to yield the
1153          * right answer.
1154          */
1155         return TimeZoneFaster(t);
1156 }
1157
1158 static int
1159 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1160 {
1161         guint32 timeval;
1162         nstime_t ts;
1163
1164         timeval = tvb_get_letohl(tvb, offset);
1165         if (timeval == 0xffffffff) {
1166                 proto_tree_add_text(tree, tvb, offset, 4,
1167                     "%s: No time specified (0xffffffff)",
1168                     proto_registrar_get_name(hf_date));
1169                 offset += 4;
1170                 return offset;
1171         }
1172
1173         /*
1174          * We add the local time offset.
1175          */
1176         ts.secs = timeval + LocTimeDiff(timeval);
1177         ts.nsecs = 0;
1178
1179         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1180         offset += 4;
1181
1182         return offset;
1183 }
1184
1185 static int
1186 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1187     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1188 {
1189         guint16 dos_time, dos_date;
1190         proto_item *item = NULL;
1191         proto_tree *tree = NULL;
1192         struct tm tm;
1193         time_t t;
1194         static const int mday_noleap[12] = {
1195                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1196         };
1197         static const int mday_leap[12] = {
1198                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1199         };
1200 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1201         nstime_t tv;
1202
1203         if (time_first) {
1204                 dos_time = tvb_get_letohs(tvb, offset);
1205                 dos_date = tvb_get_letohs(tvb, offset+2);
1206         } else {
1207                 dos_date = tvb_get_letohs(tvb, offset);
1208                 dos_time = tvb_get_letohs(tvb, offset+2);
1209         }
1210
1211         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1212             (dos_date == 0 && dos_time == 0)) {
1213                 /*
1214                  * No date/time specified.
1215                  */
1216                 if(parent_tree){
1217                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1218                             "%s: No time specified (0x%08x)",
1219                             proto_registrar_get_name(hf_date),
1220                             (dos_date << 16) | dos_time);
1221                 }
1222                 offset += 4;
1223                 return offset;
1224         }
1225
1226         tm.tm_sec = (dos_time&0x1f)*2;
1227         tm.tm_min = (dos_time>>5)&0x3f;
1228         tm.tm_hour = (dos_time>>11)&0x1f;
1229         tm.tm_mday = dos_date&0x1f;
1230         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1231         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1232         tm.tm_isdst = -1;
1233
1234         /*
1235          * Do some sanity checks before calling "mktime()";
1236          * "mktime()" doesn't do them, it "normalizes" out-of-range
1237          * values.
1238          */
1239         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1240            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1241            (ISLEAP(tm.tm_year + 1900) ?
1242              tm.tm_mday > mday_leap[tm.tm_mon] :
1243              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1244              (t = mktime(&tm)) == -1) {
1245                 /*
1246                  * Invalid date/time.
1247                  */
1248                 if (parent_tree) {
1249                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1250                             "%s: Invalid time",
1251                             proto_registrar_get_name(hf_date));
1252                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1253                         if (time_first) {
1254                                 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);
1255                                 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);
1256                         } else {
1257                                 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);
1258                                 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);
1259                         }
1260                 }
1261                 offset += 4;
1262                 return offset;
1263         }
1264
1265         tv.secs = t;
1266         tv.nsecs = 0;
1267
1268         if(parent_tree){
1269                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1270                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1271                 if (time_first) {
1272                         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);
1273                         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);
1274                 } else {
1275                         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);
1276                         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);
1277                 }
1278         }
1279
1280         offset += 4;
1281
1282         return offset;
1283 }
1284
1285
1286 static const value_string da_access_vals[] = {
1287         { 0,            "Open for reading"},
1288         { 1,            "Open for writing"},
1289         { 2,            "Open for reading and writing"},
1290         { 3,            "Open for execute"},
1291         {0, NULL}
1292 };
1293 static const value_string da_sharing_vals[] = {
1294         { 0,            "Compatibility mode"},
1295         { 1,            "Deny read/write/execute (exclusive)"},
1296         { 2,            "Deny write"},
1297         { 3,            "Deny read/execute"},
1298         { 4,            "Deny none"},
1299         {0, NULL}
1300 };
1301 static const value_string da_locality_vals[] = {
1302         { 0,            "Locality of reference unknown"},
1303         { 1,            "Mainly sequential access"},
1304         { 2,            "Mainly random access"},
1305         { 3,            "Random access with some locality"},
1306         {0, NULL}
1307 };
1308 static const true_false_string tfs_da_caching = {
1309         "Do not cache this file",
1310         "Caching permitted on this file"
1311 };
1312 static const true_false_string tfs_da_writetru = {
1313         "Write through enabled",
1314         "Write through disabled"
1315 };
1316 static int
1317 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1318 {
1319         guint16 mask;
1320         proto_item *item = NULL;
1321         proto_tree *tree = NULL;
1322
1323         mask = tvb_get_letohs(tvb, offset);
1324
1325         if(parent_tree){
1326                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1327                         "%s Access: 0x%04x", type, mask);
1328                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1329         }
1330
1331         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1332                 tvb, offset, 2, mask);
1333         proto_tree_add_boolean(tree, hf_smb_access_caching,
1334                 tvb, offset, 2, mask);
1335         proto_tree_add_uint(tree, hf_smb_access_locality,
1336                 tvb, offset, 2, mask);
1337         proto_tree_add_uint(tree, hf_smb_access_sharing,
1338                 tvb, offset, 2, mask);
1339         proto_tree_add_uint(tree, hf_smb_access_mode,
1340                 tvb, offset, 2, mask);
1341
1342         offset += 2;
1343
1344         return offset;
1345 }
1346
1347 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1348 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1349 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1350 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1351 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1352 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1353 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1354 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1355 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1356 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1357 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1358 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1359 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1360 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1361 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1362
1363 static const true_false_string tfs_file_attribute_read_only = {
1364         "This file is READ ONLY",
1365         "This file is NOT read only",
1366 };
1367 static const true_false_string tfs_file_attribute_hidden = {
1368         "This is a HIDDEN file",
1369         "This is NOT a hidden file"
1370 };
1371 static const true_false_string tfs_file_attribute_system = {
1372         "This is a SYSTEM file",
1373         "This is NOT a system file"
1374 };
1375 static const true_false_string tfs_file_attribute_volume = {
1376         "This is a VOLUME ID",
1377         "This is NOT a volume ID"
1378 };
1379 static const true_false_string tfs_file_attribute_directory = {
1380         "This is a DIRECTORY",
1381         "This is NOT a directory"
1382 };
1383 static const true_false_string tfs_file_attribute_archive = {
1384         "This file has been modified since last ARCHIVE",
1385         "This file has NOT been modified since last archive"
1386 };
1387 static const true_false_string tfs_file_attribute_device = {
1388         "This is a DEVICE",
1389         "This is NOT a device"
1390 };
1391 static const true_false_string tfs_file_attribute_normal = {
1392         "This file is an ordinary file",
1393         "This file has some attribute set"
1394 };
1395 static const true_false_string tfs_file_attribute_temporary = {
1396         "This is a TEMPORARY file",
1397         "This is NOT a temporary file"
1398 };
1399 static const true_false_string tfs_file_attribute_sparse = {
1400         "This is a SPARSE file",
1401         "This is NOT a sparse file"
1402 };
1403 static const true_false_string tfs_file_attribute_reparse = {
1404         "This file has an associated REPARSE POINT",
1405         "This file does NOT have an associated reparse point"
1406 };
1407 static const true_false_string tfs_file_attribute_compressed = {
1408         "This is a COMPRESSED file",
1409         "This is NOT a compressed file"
1410 };
1411 static const true_false_string tfs_file_attribute_offline = {
1412         "This file is OFFLINE",
1413         "This file is NOT offline"
1414 };
1415 static const true_false_string tfs_file_attribute_not_content_indexed = {
1416         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1417         "This file MAY be indexed by the content indexing service"
1418 };
1419 static const true_false_string tfs_file_attribute_encrypted = {
1420         "This is an ENCRYPTED file",
1421         "This is NOT an encrypted file"
1422 };
1423
1424 /*
1425  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1426  * listed as USHORT, and seem to be in packets in the wild, while in other
1427  * places they are listed as ULONG, and also seem to be.
1428  *
1429  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1430  * bytes to consume.
1431  */
1432
1433 static int
1434 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1435                         int bytes)
1436 {
1437         guint16 mask;
1438         proto_item *item = NULL;
1439         proto_tree *tree = NULL;
1440
1441         if (bytes != 2 && bytes != 4) {
1442
1443                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1444                 exit(1);
1445
1446         }
1447
1448         /*
1449          * The actual bits of interest appear to only be a USHORT
1450          */
1451         /* FIXME if this ever changes! */
1452         mask = tvb_get_letohs(tvb, offset);
1453
1454         if(parent_tree){
1455                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1456                         "File Attributes: 0x%08x", mask);
1457                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1458         }
1459         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1460                                tvb, offset, bytes, mask);       
1461         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1462                                tvb, offset, bytes, mask);
1463         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1464                                tvb, offset, bytes, mask);
1465         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1466                                tvb, offset, bytes, mask);
1467         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1468                                tvb, offset, bytes, mask);
1469         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1470                                tvb, offset, bytes, mask);
1471         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1472                                tvb, offset, bytes, mask);
1473         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1474                                tvb, offset, bytes, mask);
1475         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1476                                tvb, offset, bytes, mask);
1477         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1478                 tvb, offset, bytes, mask);
1479         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1480                 tvb, offset, bytes, mask);
1481         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1482                 tvb, offset, bytes, mask);
1483         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1484                 tvb, offset, bytes, mask);
1485         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1486                 tvb, offset, bytes, mask);
1487         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1488                 tvb, offset, bytes, mask);
1489
1490         offset += bytes;
1491
1492         return offset;
1493 }
1494
1495 /* 3.11 */
1496 static int
1497 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1498 {
1499         guint32 mask;
1500         proto_item *item = NULL;
1501         proto_tree *tree = NULL;
1502
1503         mask = tvb_get_letohl(tvb, offset);
1504
1505         if(parent_tree){
1506                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1507                         "File Attributes: 0x%08x", mask);
1508                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1509         }
1510
1511         /*
1512          * XXX - Network Monitor disagrees on some of the
1513          * bits, e.g. the bits above temporary are "atomic write"
1514          * and "transaction write", and it says nothing about the
1515          * bits above that.
1516          *
1517          * Does the Win32 API documentation, or the NT Native API book,
1518          * suggest anything?
1519          */
1520         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1521                 tvb, offset, 4, mask);
1522         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1523                 tvb, offset, 4, mask);
1524         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1525                 tvb, offset, 4, mask);
1526         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1527                 tvb, offset, 4, mask);
1528         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1529                 tvb, offset, 4, mask);
1530         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1531                 tvb, offset, 4, mask);
1532         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1533                 tvb, offset, 4, mask);
1534         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1535                 tvb, offset, 4, mask);
1536         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1537                 tvb, offset, 4, mask);
1538         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1539                 tvb, offset, 4, mask);
1540         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1541                 tvb, offset, 4, mask);
1542         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1543                 tvb, offset, 4, mask);
1544         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1545                 tvb, offset, 4, mask);
1546         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1547                 tvb, offset, 4, mask);
1548         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1549                 tvb, offset, 4, mask);
1550
1551         offset += 4;
1552
1553         return offset;
1554 }
1555
1556 static int
1557 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1558 {
1559         guint8 mask;
1560         proto_item *item = NULL;
1561         proto_tree *tree = NULL;
1562
1563         mask = tvb_get_guint8(tvb, offset);
1564
1565         if(parent_tree){
1566                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1567                         "File Attributes: 0x%02x", mask);
1568                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1569         }
1570         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1571                 tvb, offset, 1, mask);
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1573                 tvb, offset, 1, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1575                 tvb, offset, 1, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1577                 tvb, offset, 1, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1579                 tvb, offset, 1, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1581                 tvb, offset, 1, mask);
1582
1583         offset += 1;
1584
1585         return offset;
1586 }
1587
1588 static const true_false_string tfs_search_attribute_read_only = {
1589         "Include READ ONLY files in search results",
1590         "Do NOT include read only files in search results",
1591 };
1592 static const true_false_string tfs_search_attribute_hidden = {
1593         "Include HIDDEN files in search results",
1594         "Do NOT include hidden files in search results"
1595 };
1596 static const true_false_string tfs_search_attribute_system = {
1597         "Include SYSTEM files in search results",
1598         "Do NOT include system files in search results"
1599 };
1600 static const true_false_string tfs_search_attribute_volume = {
1601         "Include VOLUME IDs in search results",
1602         "Do NOT include volume IDs in search results"
1603 };
1604 static const true_false_string tfs_search_attribute_directory = {
1605         "Include DIRECTORIES in search results",
1606         "Do NOT include directories in search results"
1607 };
1608 static const true_false_string tfs_search_attribute_archive = {
1609         "Include ARCHIVE files in search results",
1610         "Do NOT include archive files in search results"
1611 };
1612
1613 static int
1614 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1615 {
1616         guint16 mask;
1617         proto_item *item = NULL;
1618         proto_tree *tree = NULL;
1619
1620         mask = tvb_get_letohs(tvb, offset);
1621
1622         if(parent_tree){
1623                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1624                         "Search Attributes: 0x%04x", mask);
1625                 tree = proto_item_add_subtree(item, ett_smb_search);
1626         }
1627
1628         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1629                 tvb, offset, 2, mask);
1630         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1631                 tvb, offset, 2, mask);
1632         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1633                 tvb, offset, 2, mask);
1634         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1635                 tvb, offset, 2, mask);
1636         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1637                 tvb, offset, 2, mask);
1638         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1639                 tvb, offset, 2, mask);
1640
1641         offset += 2;
1642         return offset;
1643 }
1644
1645 #if 0
1646 /*
1647  * XXX - this isn't used.
1648  * Is this used for anything?  NT Create AndX doesn't use it.
1649  * Is there some 16-bit attribute field with more bits than Read Only,
1650  * Hidden, System, Volume ID, Directory, and Archive?
1651  */
1652 static int
1653 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1654 {
1655         guint32 mask;
1656         proto_item *item = NULL;
1657         proto_tree *tree = NULL;
1658
1659         mask = tvb_get_letohl(tvb, offset);
1660
1661         if(parent_tree){
1662                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1663                         "File Attributes: 0x%08x", mask);
1664                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1665         }
1666         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1667                 tvb, offset, 2, mask);
1668         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1669                 tvb, offset, 2, mask);
1670         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1671                 tvb, offset, 2, mask);
1672         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1673                 tvb, offset, 2, mask);
1674         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1675                 tvb, offset, 2, mask);
1676         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1677                 tvb, offset, 2, mask);
1678         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1679                 tvb, offset, 2, mask);
1680         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1681                 tvb, offset, 2, mask);
1682         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1683                 tvb, offset, 2, mask);
1684         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1685                 tvb, offset, 2, mask);
1686         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1687                 tvb, offset, 2, mask);
1688         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1689                 tvb, offset, 2, mask);
1690         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1691                 tvb, offset, 2, mask);
1692         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1693                 tvb, offset, 2, mask);
1694         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1695                 tvb, offset, 2, mask);
1696
1697         offset += 2;
1698
1699         return offset;
1700 }
1701 #endif
1702
1703
1704 #define SERVER_CAP_RAW_MODE            0x00000001
1705 #define SERVER_CAP_MPX_MODE            0x00000002
1706 #define SERVER_CAP_UNICODE             0x00000004
1707 #define SERVER_CAP_LARGE_FILES         0x00000008
1708 #define SERVER_CAP_NT_SMBS             0x00000010
1709 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1710 #define SERVER_CAP_STATUS32            0x00000040
1711 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1712 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1713 #define SERVER_CAP_NT_FIND             0x00000200
1714 #define SERVER_CAP_DFS                 0x00001000
1715 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1716 #define SERVER_CAP_LARGE_READX         0x00004000
1717 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1718 #define SERVER_CAP_UNIX                0x00800000
1719 #define SERVER_CAP_RESERVED            0x02000000
1720 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1721 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1722 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1723 static const true_false_string tfs_server_cap_raw_mode = {
1724         "Read Raw and Write Raw are supported",
1725         "Read Raw and Write Raw are not supported"
1726 };
1727 static const true_false_string tfs_server_cap_mpx_mode = {
1728         "Read Mpx and Write Mpx are supported",
1729         "Read Mpx and Write Mpx are not supported"
1730 };
1731 static const true_false_string tfs_server_cap_unicode = {
1732         "Unicode strings are supported",
1733         "Unicode strings are not supported"
1734 };
1735 static const true_false_string tfs_server_cap_large_files = {
1736         "Large files are supported",
1737         "Large files are not supported",
1738 };
1739 static const true_false_string tfs_server_cap_nt_smbs = {
1740         "NT SMBs are supported",
1741         "NT SMBs are not supported"
1742 };
1743 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1744         "RPC remote APIs are supported",
1745         "RPC remote APIs are not supported"
1746 };
1747 static const true_false_string tfs_server_cap_nt_status = {
1748         "NT status codes are supported",
1749         "NT status codes are not supported"
1750 };
1751 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1752         "Level 2 oplocks are supported",
1753         "Level 2 oplocks are not supported"
1754 };
1755 static const true_false_string tfs_server_cap_lock_and_read = {
1756         "Lock and Read is supported",
1757         "Lock and Read is not supported"
1758 };
1759 static const true_false_string tfs_server_cap_nt_find = {
1760         "NT Find is supported",
1761         "NT Find is not supported"
1762 };
1763 static const true_false_string tfs_server_cap_dfs = {
1764         "Dfs is supported",
1765         "Dfs is not supported"
1766 };
1767 static const true_false_string tfs_server_cap_infolevel_passthru = {
1768         "NT information level request passthrough is supported",
1769         "NT information level request passthrough is not supported"
1770 };
1771 static const true_false_string tfs_server_cap_large_readx = {
1772         "Large Read andX is supported",
1773         "Large Read andX is not supported"
1774 };
1775 static const true_false_string tfs_server_cap_large_writex = {
1776         "Large Write andX is supported",
1777         "Large Write andX is not supported"
1778 };
1779 static const true_false_string tfs_server_cap_unix = {
1780         "UNIX extensions are supported",
1781         "UNIX extensions are not supported"
1782 };
1783 static const true_false_string tfs_server_cap_reserved = {
1784         "Reserved",
1785         "Reserved"
1786 };
1787 static const true_false_string tfs_server_cap_bulk_transfer = {
1788         "Bulk Read and Bulk Write are supported",
1789         "Bulk Read and Bulk Write are not supported"
1790 };
1791 static const true_false_string tfs_server_cap_compressed_data = {
1792         "Compressed data transfer is supported",
1793         "Compressed data transfer is not supported"
1794 };
1795 static const true_false_string tfs_server_cap_extended_security = {
1796         "Extended security exchanges are supported",
1797         "Extended security exchanges are not supported"
1798 };
1799 static int
1800 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1801 {
1802         guint32 mask;
1803         proto_item *item = NULL;
1804         proto_tree *tree = NULL;
1805
1806         mask = tvb_get_letohl(tvb, offset);
1807
1808         if(parent_tree){
1809                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1810                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1811         }
1812
1813         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1814                 tvb, offset, 4, mask);
1815         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1816                 tvb, offset, 4, mask);
1817         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1818                 tvb, offset, 4, mask);
1819         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1820                 tvb, offset, 4, mask);
1821         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1822                 tvb, offset, 4, mask);
1823         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1824                 tvb, offset, 4, mask);
1825         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1826                 tvb, offset, 4, mask);
1827         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1828                 tvb, offset, 4, mask);
1829         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1830                 tvb, offset, 4, mask);
1831         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1832                 tvb, offset, 4, mask);
1833         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1834                 tvb, offset, 4, mask);
1835         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1836                 tvb, offset, 4, mask);
1837         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1838                 tvb, offset, 4, mask);
1839         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1840                 tvb, offset, 4, mask);
1841         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1842                 tvb, offset, 4, mask);
1843         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1844                 tvb, offset, 4, mask);
1845         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1846                 tvb, offset, 4, mask);
1847         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1848                 tvb, offset, 4, mask);
1849         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1850                 tvb, offset, 4, mask);
1851
1852         return mask;
1853 }
1854
1855 #define RAWMODE_READ   0x01
1856 #define RAWMODE_WRITE  0x02
1857 static const true_false_string tfs_rm_read = {
1858         "Read Raw is supported",
1859         "Read Raw is not supported"
1860 };
1861 static const true_false_string tfs_rm_write = {
1862         "Write Raw is supported",
1863         "Write Raw is not supported"
1864 };
1865
1866 static int
1867 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1868 {
1869         guint16 mask;
1870         proto_item *item = NULL;
1871         proto_tree *tree = NULL;
1872
1873         mask = tvb_get_letohs(tvb, offset);
1874
1875         if(parent_tree){
1876                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1877                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1878         }
1879
1880         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1881         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1882
1883         offset += 2;
1884
1885         return offset;
1886 }
1887
1888 #define SECURITY_MODE_MODE             0x01
1889 #define SECURITY_MODE_PASSWORD         0x02
1890 #define SECURITY_MODE_SIGNATURES       0x04
1891 #define SECURITY_MODE_SIG_REQUIRED     0x08
1892 static const true_false_string tfs_sm_mode = {
1893         "USER security mode",
1894         "SHARE security mode"
1895 };
1896 static const true_false_string tfs_sm_password = {
1897         "ENCRYPTED password. Use challenge/response",
1898         "PLAINTEXT password"
1899 };
1900 static const true_false_string tfs_sm_signatures = {
1901         "Security signatures ENABLED",
1902         "Security signatures NOT enabled"
1903 };
1904 static const true_false_string tfs_sm_sig_required = {
1905         "Security signatures REQUIRED",
1906         "Security signatures NOT required"
1907 };
1908
1909 static int
1910 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1911 {
1912         guint16 mask = 0;
1913         proto_item *item = NULL;
1914         proto_tree *tree = NULL;
1915
1916         switch(wc){
1917         case 13:
1918                 mask = tvb_get_letohs(tvb, offset);
1919                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1920                                 "Security Mode: 0x%04x", mask);
1921                 tree = proto_item_add_subtree(item, ett_smb_mode);
1922                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1923                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1924                 offset += 2;
1925                 break;
1926
1927         case 17:
1928                 mask = tvb_get_guint8(tvb, offset);
1929                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1930                                 "Security Mode: 0x%02x", mask);
1931                 tree = proto_item_add_subtree(item, ett_smb_mode);
1932                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1933                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1934                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1935                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1936                 offset += 1;
1937                 break;
1938         }
1939
1940         return offset;
1941 }
1942
1943 static int
1944 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
1945 {
1946         proto_item *it = NULL;
1947         proto_tree *tr = NULL;
1948         guint16 bc;
1949         guint8 wc;
1950
1951         WORD_COUNT;
1952
1953         BYTE_COUNT;
1954
1955         if(tree){
1956                 it = proto_tree_add_text(tree, tvb, offset, bc,
1957                                 "Requested Dialects");
1958                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1959         }
1960
1961         while(bc){
1962                 int len;
1963                 const guint8 *str;
1964                 proto_item *dit = NULL;
1965                 proto_tree *dtr = NULL;
1966
1967                 /* XXX - what if this runs past bc? */
1968                 len = tvb_strsize(tvb, offset+1);
1969                 str = tvb_get_ptr(tvb, offset+1, len);
1970
1971                 if(tr){
1972                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
1973                                         "Dialect: %s", str);
1974                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
1975                 }
1976
1977                 /* Buffer Format */
1978                 CHECK_BYTE_COUNT(1);
1979                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
1980                         TRUE);
1981                 COUNT_BYTES(1);
1982
1983                 /*Dialect Name */
1984                 CHECK_BYTE_COUNT(len);
1985                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
1986                         len, str);
1987                 COUNT_BYTES(len);
1988         }
1989
1990         END_OF_SMB
1991
1992         return offset;
1993 }
1994
1995 static int
1996 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
1997 {
1998         smb_info_t *si = pinfo->private_data;
1999         guint8 wc;
2000         guint16 dialect;
2001         const char *dn;
2002         int dn_len;
2003         guint16 bc;
2004         guint16 ekl=0;
2005         guint32 caps=0;
2006         gint16 tz;
2007
2008         WORD_COUNT;
2009
2010         /* Dialect Index */
2011         dialect = tvb_get_letohs(tvb, offset);
2012         switch(wc){
2013         case 1:
2014                 if(dialect==0xffff){
2015                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2016                                 tvb, offset, 2, dialect,
2017                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2018                 } else {
2019                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2020                                 tvb, offset, 2, dialect);
2021                 }
2022                 break;
2023         case 13:
2024                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2025                         tvb, offset, 2, dialect,
2026                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2027                 break;
2028         case 17:
2029                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2030                         tvb, offset, 2, dialect,
2031                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2032                 break;
2033         default:
2034                 proto_tree_add_text(tree, tvb, offset, wc*2,
2035                         "Words for unknown response format");
2036                 offset += wc*2;
2037                 goto bytecount;
2038         }
2039         offset += 2;
2040
2041         switch(wc){
2042         case 13:
2043                 /* Security Mode */
2044                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2045
2046                 /* Maximum Transmit Buffer Size */
2047                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2048                         tvb, offset, 2, TRUE);
2049                 offset += 2;
2050
2051                 /* Maximum Multiplex Count */
2052                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2053                         tvb, offset, 2, TRUE);
2054                 offset += 2;
2055
2056                 /* Maximum Vcs Number */
2057                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2058                         tvb, offset, 2, TRUE);
2059                 offset += 2;
2060
2061                 /* raw mode */
2062                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2063
2064                 /* session key */
2065                 proto_tree_add_item(tree, hf_smb_session_key,
2066                         tvb, offset, 4, TRUE);
2067                 offset += 4;
2068
2069                 /* current time and date at server */
2070                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2071                     TRUE);
2072
2073                 /* time zone */
2074                 tz = tvb_get_letohs(tvb, offset);
2075                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2076                 offset += 2;
2077
2078                 /* encryption key length */
2079                 ekl = tvb_get_letohs(tvb, offset);
2080                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2081                 offset += 2;
2082
2083                 /* 2 reserved bytes */
2084                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2085                 offset += 2;
2086
2087                 break;
2088
2089         case 17:
2090                 /* Security Mode */
2091                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2092
2093                 /* Maximum Multiplex Count */
2094                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2095                         tvb, offset, 2, TRUE);
2096                 offset += 2;
2097
2098                 /* Maximum Vcs Number */
2099                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2100                         tvb, offset, 2, TRUE);
2101                 offset += 2;
2102
2103                 /* Maximum Transmit Buffer Size */
2104                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2105                         tvb, offset, 4, TRUE);
2106                 offset += 4;
2107
2108                 /* maximum raw buffer size */
2109                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2110                         tvb, offset, 4, TRUE);
2111                 offset += 4;
2112
2113                 /* session key */
2114                 proto_tree_add_item(tree, hf_smb_session_key,
2115                         tvb, offset, 4, TRUE);
2116                 offset += 4;
2117
2118                 /* server capabilities */
2119                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2120                 offset += 4;
2121
2122                 /* system time */
2123                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2124                                 hf_smb_system_time);
2125
2126                 /* time zone */
2127                 tz = tvb_get_letohs(tvb, offset);
2128                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2129                         tvb, offset, 2, tz,
2130                         "Server Time Zone: %d min from UTC", tz);
2131                 offset += 2;
2132
2133                 /* encryption key length */
2134                 ekl = tvb_get_guint8(tvb, offset);
2135                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2136                         tvb, offset, 1, ekl);
2137                 offset += 1;
2138
2139                 break;
2140         }
2141
2142         BYTE_COUNT;
2143
2144         switch(wc){
2145         case 13:
2146                 /* challenge/response encryption key */
2147                 if(ekl){
2148                         CHECK_BYTE_COUNT(ekl);
2149                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2150                         COUNT_BYTES(ekl);
2151                 }
2152
2153                 /*
2154                  * Primary domain.
2155                  *
2156                  * XXX - not present if negotiated dialect isn't
2157                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2158                  * have to see the request, or assume what dialect strings
2159                  * were sent, to determine that.
2160                  *
2161                  * Is this something other than a primary domain if the
2162                  * negotiated dialect is Windows for Workgroups 3.1a?
2163                  * It appears to be 8 bytes of binary data in at least
2164                  * one capture - is that an encryption key or something
2165                  * such as that?
2166                  */
2167                 dn = get_unicode_or_ascii_string(tvb, &offset,
2168                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2169                 if (dn == NULL)
2170                         goto endofcommand;
2171                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2172                         offset, dn_len,dn);
2173                 COUNT_BYTES(dn_len);
2174                 break;
2175
2176         case 17:
2177                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2178                         /* challenge/response encryption key */
2179                         /* XXX - is this aligned on an even boundary? */
2180                         if(ekl){
2181                                 CHECK_BYTE_COUNT(ekl);
2182                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2183                                         tvb, offset, ekl, TRUE);
2184                                 COUNT_BYTES(ekl);
2185                         }
2186
2187                         /* domain */
2188                         /* this string is special, unicode is flagged in caps */
2189                         /* This string is NOT padded to be 16bit aligned.
2190                            (seen in actual capture)
2191                            XXX - I've seen a capture where it appears to be
2192                            so aligned, but I've also seen captures where
2193                            it is.  The captures where it appeared to be
2194                            aligned may have been from buggy servers. */
2195                         /* However, don't get rid of existing setting */
2196                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2197                           si->unicode;
2198
2199                         dn = get_unicode_or_ascii_string(tvb,
2200                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2201                                 &bc);
2202                         if (dn == NULL)
2203                                 goto endofcommand;
2204                         proto_tree_add_string(tree, hf_smb_primary_domain,
2205                                 tvb, offset, dn_len, dn);
2206                         COUNT_BYTES(dn_len);
2207
2208                         /* server name, seen in w2k pro capture */
2209                         dn = get_unicode_or_ascii_string(tvb,
2210                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2211                                 &bc);
2212                         if (dn == NULL)
2213                                 goto endofcommand;
2214                         proto_tree_add_string(tree, hf_smb_server,
2215                                 tvb, offset, dn_len, dn);
2216                         COUNT_BYTES(dn_len);
2217
2218                 } else {
2219                         proto_item *blob_item;
2220                         guint16 sbloblen;
2221
2222                         /* guid */
2223                         /* XXX - show it in the standard Microsoft format
2224                            for GUIDs? */
2225                         CHECK_BYTE_COUNT(16);
2226                         proto_tree_add_item(tree, hf_smb_server_guid,
2227                                 tvb, offset, 16, TRUE);
2228                         COUNT_BYTES(16);
2229
2230                         /* security blob */
2231                         /* If it runs past the end of the captured data, don't
2232                          * try to put all of it into the protocol tree as the
2233                          * raw security blob; we might get an exception on 
2234                          * short frames and then we will not see anything at all
2235                          * of the security blob.
2236                          */
2237                         sbloblen=bc;
2238                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2239                                 sbloblen=tvb_length_remaining(tvb,offset);
2240                         }
2241                         blob_item = proto_tree_add_item(
2242                                 tree, hf_smb_security_blob,
2243                                 tvb, offset, sbloblen, TRUE);
2244
2245                         /* 
2246                          * If Extended security and BCC == 16, then raw 
2247                          * NTLMSSP is in use. We need to save this info
2248                          */
2249  
2250                         if(bc){
2251                                 tvbuff_t *gssapi_tvb;
2252                                 proto_tree *gssapi_tree;
2253
2254                                 gssapi_tree = proto_item_add_subtree(
2255                                         blob_item, ett_smb_secblob);
2256
2257                                 /*
2258                                  * Set the reported length of this to
2259                                  * the reported length of the blob,
2260                                  * rather than the amount of data
2261                                  * available from the blob, so that
2262                                  * we'll throw the right exception if
2263                                  * it's too short.
2264                                  */
2265                                 gssapi_tvb = tvb_new_subset(
2266                                         tvb, offset, sbloblen, bc);
2267
2268                                 call_dissector(
2269                                         gssapi_handle, gssapi_tvb, pinfo,
2270                                         gssapi_tree);
2271
2272                                 if (si->ct)
2273                                   si->ct->raw_ntlmssp = 0;
2274
2275                                 COUNT_BYTES(bc);
2276                         }
2277                         else { 
2278
2279                           /*
2280                            * There is no blob. We just have to make sure
2281                            * that subsequent routines know to call the 
2282                            * right things ...
2283                            */
2284
2285                           if (si->ct)
2286                             si->ct->raw_ntlmssp = 1;
2287
2288                         }
2289                 }
2290                 break;
2291         }
2292
2293         END_OF_SMB
2294
2295         return offset;
2296 }
2297
2298
2299 static int
2300 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2301 {
2302         smb_info_t *si = pinfo->private_data;
2303         int dn_len;
2304         const char *dn;
2305         guint8 wc;
2306         guint16 bc;
2307
2308         WORD_COUNT;
2309
2310         BYTE_COUNT;
2311
2312         /* buffer format */
2313         CHECK_BYTE_COUNT(1);
2314         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2315         COUNT_BYTES(1);
2316
2317         /* dir name */
2318         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2319                 FALSE, FALSE, &bc);
2320         if (dn == NULL)
2321                 goto endofcommand;
2322         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2323                 dn);
2324         COUNT_BYTES(dn_len);
2325
2326         if (check_col(pinfo->cinfo, COL_INFO)) {
2327                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2328                     format_text(dn, strlen(dn)));
2329         }
2330
2331         END_OF_SMB
2332
2333         return offset;
2334 }
2335
2336 static int
2337 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2338 {
2339         guint8 wc;
2340         guint16 bc;
2341
2342         WORD_COUNT;
2343
2344         BYTE_COUNT;
2345
2346         END_OF_SMB
2347
2348         return offset;
2349 }
2350
2351 static int
2352 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2353 {
2354         guint16 ec, bc;
2355         guint8 wc;
2356
2357         WORD_COUNT;
2358
2359         /* echo count */
2360         ec = tvb_get_letohs(tvb, offset);
2361         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2362         offset += 2;
2363
2364         BYTE_COUNT;
2365
2366         if (bc != 0) {
2367                 /* echo data */
2368                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2369                 COUNT_BYTES(bc);
2370         }
2371
2372         END_OF_SMB
2373
2374         return offset;
2375 }
2376
2377 static int
2378 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2379 {
2380         guint16 bc;
2381         guint8 wc;
2382
2383         WORD_COUNT;
2384
2385         /* echo sequence number */
2386         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2387         offset += 2;
2388
2389         BYTE_COUNT;
2390
2391         if (bc != 0) {
2392                 /* echo data */
2393                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2394                 COUNT_BYTES(bc);
2395         }
2396
2397         END_OF_SMB
2398
2399         return offset;
2400 }
2401
2402 static int
2403 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2404 {
2405         smb_info_t *si = pinfo->private_data;
2406         int an_len, pwlen;
2407         const char *an;
2408         guint8 wc;
2409         guint16 bc;
2410
2411         WORD_COUNT;
2412
2413         BYTE_COUNT;
2414
2415         /* buffer format */
2416         CHECK_BYTE_COUNT(1);
2417         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2418         COUNT_BYTES(1);
2419
2420         /* Path */
2421         an = get_unicode_or_ascii_string(tvb, &offset,
2422                 si->unicode, &an_len, FALSE, FALSE, &bc);
2423         if (an == NULL)
2424                 goto endofcommand;
2425         proto_tree_add_string(tree, hf_smb_path, tvb,
2426                 offset, an_len, an);
2427         COUNT_BYTES(an_len);
2428
2429         if (check_col(pinfo->cinfo, COL_INFO)) {
2430                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2431                     format_text(an, strlen(an)));
2432         }
2433
2434         /* buffer format */
2435         CHECK_BYTE_COUNT(1);
2436         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2437         COUNT_BYTES(1);
2438
2439         /* password, ANSI */
2440         /* XXX - what if this runs past bc? */
2441         pwlen = tvb_strsize(tvb, offset);
2442         CHECK_BYTE_COUNT(pwlen);
2443         proto_tree_add_item(tree, hf_smb_password,
2444                 tvb, offset, pwlen, TRUE);
2445         COUNT_BYTES(pwlen);
2446
2447         /* buffer format */
2448         CHECK_BYTE_COUNT(1);
2449         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2450         COUNT_BYTES(1);
2451
2452         /* Service */
2453         /*
2454          * XXX - the SNIA CIFS spec "Strings that are never passed in
2455          * Unicode are: ... The service name string in the
2456          * Tree_Connect_AndX SMB".  Is that claim false?
2457          */
2458         an = get_unicode_or_ascii_string(tvb, &offset,
2459                 si->unicode, &an_len, FALSE, FALSE, &bc);
2460         if (an == NULL)
2461                 goto endofcommand;
2462         proto_tree_add_string(tree, hf_smb_service, tvb,
2463                 offset, an_len, an);
2464         COUNT_BYTES(an_len);
2465
2466         END_OF_SMB
2467
2468         return offset;
2469 }
2470
2471 static int
2472 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2473 {
2474         guint8 wc;
2475         guint16 bc;
2476
2477         WORD_COUNT;
2478
2479         /* Maximum Buffer Size */
2480         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2481         offset += 2;
2482
2483         /* tid */
2484         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2485         offset += 2;
2486
2487         BYTE_COUNT;
2488
2489         END_OF_SMB
2490
2491         return offset;
2492 }
2493
2494
2495 static const true_false_string tfs_of_create = {
2496         "Create file if it does not exist",
2497         "Fail if file does not exist"
2498 };
2499 static const value_string of_open[] = {
2500         { 0,            "Fail if file exists"},
2501         { 1,            "Open file if it exists"},
2502         { 2,            "Truncate file if it exists"},
2503         {0, NULL}
2504 };
2505 static int
2506 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2507 {
2508         guint16 mask;
2509         proto_item *item = NULL;
2510         proto_tree *tree = NULL;
2511
2512         mask = tvb_get_letohs(tvb, offset);
2513
2514         if(parent_tree){
2515                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2516                         "Open Function: 0x%04x", mask);
2517                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2518         }
2519
2520         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2521                 tvb, offset, 2, mask);
2522         proto_tree_add_uint(tree, hf_smb_open_function_open,
2523                 tvb, offset, 2, mask);
2524
2525         offset += 2;
2526
2527         return offset;
2528 }
2529
2530
2531 static const true_false_string tfs_mf_file = {
2532         "Target must be a file",
2533         "Target needn't be a file"
2534 };
2535 static const true_false_string tfs_mf_dir = {
2536         "Target must be a directory",
2537         "Target needn't be a directory"
2538 };
2539 static const true_false_string tfs_mf_verify = {
2540         "MUST verify all writes",
2541         "Don't have to verify writes"
2542 };
2543 static int
2544 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2545 {
2546         guint16 mask;
2547         proto_item *item = NULL;
2548         proto_tree *tree = NULL;
2549
2550         mask = tvb_get_letohs(tvb, offset);
2551
2552         if(parent_tree){
2553                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2554                         "Flags: 0x%04x", mask);
2555                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2556         }
2557
2558         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2559                 tvb, offset, 2, mask);
2560         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2561                 tvb, offset, 2, mask);
2562         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2563                 tvb, offset, 2, mask);
2564
2565         offset += 2;
2566
2567         return offset;
2568 }
2569
2570 static const true_false_string tfs_cf_mode = {
2571         "ASCII",
2572         "Binary"
2573 };
2574 static const true_false_string tfs_cf_tree_copy = {
2575         "Copy is a tree copy",
2576         "Copy is a file copy"
2577 };
2578 static const true_false_string tfs_cf_ea_action = {
2579         "Fail copy",
2580         "Discard EAs"
2581 };
2582 static int
2583 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2584 {
2585         guint16 mask;
2586         proto_item *item = NULL;
2587         proto_tree *tree = NULL;
2588
2589         mask = tvb_get_letohs(tvb, offset);
2590
2591         if(parent_tree){
2592                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2593                         "Flags: 0x%04x", mask);
2594                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2595         }
2596
2597         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2598                 tvb, offset, 2, mask);
2599         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2600                 tvb, offset, 2, mask);
2601         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2602                 tvb, offset, 2, mask);
2603         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2604                 tvb, offset, 2, mask);
2605         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2606                 tvb, offset, 2, mask);
2607         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2608                 tvb, offset, 2, mask);
2609         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2610                 tvb, offset, 2, mask);
2611
2612         offset += 2;
2613
2614         return offset;
2615 }
2616
2617 static int
2618 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2619 {
2620         smb_info_t *si = pinfo->private_data;
2621         int fn_len;
2622         guint16 tid;
2623         guint16 bc;
2624         guint8 wc;
2625         const char *fn;
2626
2627         WORD_COUNT;
2628
2629         /* tid */
2630         tid = tvb_get_letohs(tvb, offset);
2631         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2632                 "TID (target): 0x%04x", tid);
2633         offset += 2;
2634
2635         /* open function */
2636         offset = dissect_open_function(tvb, tree, offset);
2637
2638         /* move flags */
2639         offset = dissect_move_flags(tvb, tree, offset);
2640
2641         BYTE_COUNT;
2642
2643         /* buffer format */
2644         CHECK_BYTE_COUNT(1);
2645         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2646         COUNT_BYTES(1);
2647
2648         /* file name */
2649         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2650                 FALSE, FALSE, &bc);
2651         if (fn == NULL)
2652                 goto endofcommand;
2653         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2654                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
2655         COUNT_BYTES(fn_len);
2656
2657         if (check_col(pinfo->cinfo, COL_INFO)) {
2658                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
2659                     format_text(fn, strlen(fn)));
2660         }
2661
2662         /* buffer format */
2663         CHECK_BYTE_COUNT(1);
2664         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2665         COUNT_BYTES(1);
2666
2667         /* file name */
2668         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2669                 FALSE, FALSE, &bc);
2670         if (fn == NULL)
2671                 goto endofcommand;
2672         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2673                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
2674         COUNT_BYTES(fn_len);
2675
2676         if (check_col(pinfo->cinfo, COL_INFO)) {
2677                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
2678                     format_text(fn, strlen(fn)));
2679         }
2680
2681         END_OF_SMB
2682
2683         return offset;
2684 }
2685
2686 static int
2687 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2688 {
2689         smb_info_t *si = pinfo->private_data;
2690         int fn_len;
2691         guint16 tid;
2692         guint16 bc;
2693         guint8 wc;
2694         const char *fn;
2695
2696         WORD_COUNT;
2697
2698         /* tid */
2699         tid = tvb_get_letohs(tvb, offset);
2700         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2701                 "TID (target): 0x%04x", tid);
2702         offset += 2;
2703
2704         /* open function */
2705         offset = dissect_open_function(tvb, tree, offset);
2706
2707         /* copy flags */
2708         offset = dissect_copy_flags(tvb, tree, offset);
2709
2710         BYTE_COUNT;
2711
2712         /* buffer format */
2713         CHECK_BYTE_COUNT(1);
2714         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2715         COUNT_BYTES(1);
2716
2717         /* file name */
2718         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2719                 FALSE, FALSE, &bc);
2720         if (fn == NULL)
2721                 goto endofcommand;
2722         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2723                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
2724         COUNT_BYTES(fn_len);
2725
2726         if (check_col(pinfo->cinfo, COL_INFO)) {
2727                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
2728                     format_text(fn, strlen(fn)));
2729         }
2730
2731         /* buffer format */
2732         CHECK_BYTE_COUNT(1);
2733         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2734         COUNT_BYTES(1);
2735
2736         /* file name */
2737         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2738                 FALSE, FALSE, &bc);
2739         if (fn == NULL)
2740                 goto endofcommand;
2741         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2742                 fn_len, fn, "Destination File Name: %s",
2743                 format_text(fn, strlen(fn)));
2744         COUNT_BYTES(fn_len);
2745
2746         if (check_col(pinfo->cinfo, COL_INFO)) {
2747                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s",
2748                     format_text(fn, strlen(fn)));
2749         }
2750
2751         END_OF_SMB
2752
2753         return offset;
2754 }
2755
2756 static int
2757 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2758 {
2759         smb_info_t *si = pinfo->private_data;
2760         int fn_len;
2761         const char *fn;
2762         guint8 wc;
2763         guint16 bc;
2764
2765         WORD_COUNT;
2766
2767         /* # of files moved */
2768         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2769         offset += 2;
2770
2771         BYTE_COUNT;
2772
2773         /* buffer format */
2774         CHECK_BYTE_COUNT(1);
2775         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2776         COUNT_BYTES(1);
2777
2778         /* file name */
2779         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2780                 FALSE, FALSE, &bc);
2781         if (fn == NULL)
2782                 goto endofcommand;
2783         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2784                 fn);
2785         COUNT_BYTES(fn_len);
2786
2787         END_OF_SMB
2788
2789         return offset;
2790 }
2791
2792 static int
2793 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2794 {
2795         smb_info_t *si = pinfo->private_data;
2796         int fn_len;
2797         const char *fn;
2798         guint8 wc;
2799         guint16 bc;
2800
2801         WORD_COUNT;
2802
2803         /* desired access */
2804         offset = dissect_access(tvb, tree, offset, "Desired");
2805
2806         /* Search Attributes */
2807         offset = dissect_search_attributes(tvb, tree, offset);
2808
2809         BYTE_COUNT;
2810
2811         /* buffer format */
2812         CHECK_BYTE_COUNT(1);
2813         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2814         COUNT_BYTES(1);
2815
2816         /* file name */
2817         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2818                 FALSE, FALSE, &bc);
2819         if (fn == NULL)
2820                 goto endofcommand;
2821         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2822                 fn);
2823         COUNT_BYTES(fn_len);
2824
2825         if (check_col(pinfo->cinfo, COL_INFO)) {
2826                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2827                     format_text(fn, strlen(fn)));
2828         }
2829
2830         END_OF_SMB
2831
2832         return offset;
2833 }
2834
2835 void
2836 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2837     int len, guint16 fid)
2838 {
2839         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2840         if (check_col(pinfo->cinfo, COL_INFO))
2841                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2842 }
2843
2844 static int
2845 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2846 {
2847         guint8 wc;
2848         guint16 bc;
2849         guint16 fid;
2850
2851         WORD_COUNT;
2852
2853         /* fid */
2854         fid = tvb_get_letohs(tvb, offset);
2855         add_fid(tvb, pinfo, tree, offset, 2, fid);
2856         offset += 2;
2857
2858         /* File Attributes */
2859         offset = dissect_file_attributes(tvb, tree, offset, 2);
2860
2861         /* last write time */
2862         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2863
2864         /* File Size */
2865         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2866         offset += 4;
2867
2868         /* granted access */
2869         offset = dissect_access(tvb, tree, offset, "Granted");
2870
2871         BYTE_COUNT;
2872
2873         END_OF_SMB
2874
2875         return offset;
2876 }
2877
2878 static int
2879 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2880 {
2881         guint8 wc;
2882         guint16 bc;
2883         guint16 fid;
2884
2885         WORD_COUNT;
2886
2887         /* fid */
2888         fid = tvb_get_letohs(tvb, offset);
2889         add_fid(tvb, pinfo, tree, offset, 2, fid);
2890         offset += 2;
2891
2892         BYTE_COUNT;
2893
2894         END_OF_SMB
2895
2896         return offset;
2897 }
2898
2899 static int
2900 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2901 {
2902         smb_info_t *si = pinfo->private_data;
2903         int fn_len;
2904         const char *fn;
2905         guint8 wc;
2906         guint16 bc;
2907
2908         WORD_COUNT;
2909
2910         /* file attributes */
2911         offset = dissect_file_attributes(tvb, tree, offset, 2);
2912
2913         /* creation time */
2914         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2915
2916         BYTE_COUNT;
2917
2918         /* buffer format */
2919         CHECK_BYTE_COUNT(1);
2920         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2921         COUNT_BYTES(1);
2922
2923         /* File Name */
2924         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2925                 FALSE, FALSE, &bc);
2926         if (fn == NULL)
2927                 goto endofcommand;
2928         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2929                 fn);
2930         COUNT_BYTES(fn_len);
2931
2932         if (check_col(pinfo->cinfo, COL_INFO)) {
2933                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2934                     format_text(fn, strlen(fn)));
2935         }
2936
2937         END_OF_SMB
2938
2939         return offset;
2940 }
2941
2942 static int
2943 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2944 {
2945         guint8 wc;
2946         guint16 bc, fid;
2947
2948         WORD_COUNT;
2949
2950         /* fid */
2951         fid = tvb_get_letohs(tvb, offset);
2952         add_fid(tvb, pinfo, tree, offset, 2, fid);
2953         offset += 2;
2954
2955         /* last write time */
2956         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2957
2958         BYTE_COUNT;
2959
2960         END_OF_SMB
2961
2962         return offset;
2963 }
2964
2965 static int
2966 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2967 {
2968         smb_info_t *si = pinfo->private_data;
2969         int fn_len;
2970         const char *fn;
2971         guint8 wc;
2972         guint16 bc;
2973
2974         WORD_COUNT;
2975
2976         /* search attributes */
2977         offset = dissect_search_attributes(tvb, tree, offset);
2978
2979         BYTE_COUNT;
2980
2981         /* buffer format */
2982         CHECK_BYTE_COUNT(1);
2983         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2984         COUNT_BYTES(1);
2985
2986         /* file name */
2987         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2988                 FALSE, FALSE, &bc);
2989         if (fn == NULL)
2990                 goto endofcommand;
2991         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2992                 fn);
2993         COUNT_BYTES(fn_len);
2994
2995         if (check_col(pinfo->cinfo, COL_INFO)) {
2996                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2997                     format_text(fn, strlen(fn)));
2998         }
2999
3000         END_OF_SMB
3001
3002         return offset;
3003 }
3004
3005 static int
3006 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3007 {
3008         smb_info_t *si = pinfo->private_data;
3009         int fn_len;
3010         const char *fn;
3011         guint8 wc;
3012         guint16 bc;
3013
3014         WORD_COUNT;
3015
3016         /* search attributes */
3017         offset = dissect_search_attributes(tvb, tree, offset);
3018
3019         BYTE_COUNT;
3020
3021         /* buffer format */
3022         CHECK_BYTE_COUNT(1);
3023         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3024         COUNT_BYTES(1);
3025
3026         /* old file name */
3027         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3028                 FALSE, FALSE, &bc);
3029         if (fn == NULL)
3030                 goto endofcommand;
3031         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3032                 fn);
3033         COUNT_BYTES(fn_len);
3034
3035         if (check_col(pinfo->cinfo, COL_INFO)) {
3036                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3037                     format_text(fn, strlen(fn)));
3038         }
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, ", New Name: %s",
3056                     format_text(fn, strlen(fn)));
3057         }
3058
3059         END_OF_SMB
3060
3061         return offset;
3062 }
3063
3064 static int
3065 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3066 {
3067         smb_info_t *si = pinfo->private_data;
3068         int fn_len;
3069         const char *fn;
3070         guint8 wc;
3071         guint16 bc;
3072
3073         WORD_COUNT;
3074
3075         /* search attributes */
3076         offset = dissect_search_attributes(tvb, tree, offset);
3077
3078         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3079         offset += 2;
3080
3081         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3082         offset += 4;
3083
3084         BYTE_COUNT;
3085
3086         /* buffer format */
3087         CHECK_BYTE_COUNT(1);
3088         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3089         COUNT_BYTES(1);
3090
3091         /* old file name */
3092         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3093                 FALSE, FALSE, &bc);
3094         if (fn == NULL)
3095                 goto endofcommand;
3096         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3097                 fn);
3098         COUNT_BYTES(fn_len);
3099
3100         if (check_col(pinfo->cinfo, COL_INFO)) {
3101                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3102                     format_text(fn, strlen(fn)));
3103         }
3104
3105         /* buffer format */
3106         CHECK_BYTE_COUNT(1);
3107         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3108         COUNT_BYTES(1);
3109
3110         /* file name */
3111         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3112                 FALSE, FALSE, &bc);
3113         if (fn == NULL)
3114                 goto endofcommand;
3115         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3116                 fn);
3117         COUNT_BYTES(fn_len);
3118
3119         if (check_col(pinfo->cinfo, COL_INFO)) {
3120                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3121                     format_text(fn, strlen(fn)));
3122         }
3123
3124         END_OF_SMB
3125
3126         return offset;
3127 }
3128
3129
3130 static int
3131 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3132 {
3133         smb_info_t *si = pinfo->private_data;
3134         guint16 bc;
3135         guint8 wc;
3136         const char *fn;
3137         int fn_len;
3138
3139         WORD_COUNT;
3140
3141         BYTE_COUNT;
3142
3143         /* Buffer Format */
3144         CHECK_BYTE_COUNT(1);
3145         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3146         COUNT_BYTES(1);
3147
3148         /* File Name */
3149         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3150                 FALSE, FALSE, &bc);
3151         if (fn == NULL)
3152                 goto endofcommand;
3153         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3154                 fn);
3155         COUNT_BYTES(fn_len);
3156
3157         if (check_col(pinfo->cinfo, COL_INFO)) {
3158                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3159                     format_text(fn, strlen(fn)));
3160         }
3161
3162         END_OF_SMB
3163
3164         return offset;
3165 }
3166
3167 static int
3168 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3169 {
3170         guint16 bc;
3171         guint8 wc;
3172
3173         WORD_COUNT;
3174
3175         /* File Attributes */
3176         offset = dissect_file_attributes(tvb, tree, offset, 2);
3177
3178         /* Last Write Time */
3179         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3180
3181         /* File Size */
3182         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3183         offset += 4;
3184
3185         /* 10 reserved bytes */
3186         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3187         offset += 10;
3188
3189         BYTE_COUNT;
3190
3191         END_OF_SMB
3192
3193         return offset;
3194 }
3195
3196 static int
3197 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3198 {
3199         smb_info_t *si = pinfo->private_data;
3200         int fn_len;
3201         const char *fn;
3202         guint8 wc;
3203         guint16 bc;
3204
3205         WORD_COUNT;
3206
3207         /* file attributes */
3208         offset = dissect_file_attributes(tvb, tree, offset, 2);
3209
3210         /* last write time */
3211         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3212
3213         /* 10 reserved bytes */
3214         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3215         offset += 10;
3216
3217         BYTE_COUNT;
3218
3219         /* buffer format */
3220         CHECK_BYTE_COUNT(1);
3221         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3222         COUNT_BYTES(1);
3223
3224         /* file name */
3225         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3226                 FALSE, FALSE, &bc);
3227         if (fn == NULL)
3228                 goto endofcommand;
3229         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3230                 fn);
3231         COUNT_BYTES(fn_len);
3232
3233         if (check_col(pinfo->cinfo, COL_INFO)) {
3234                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3235                     format_text(fn, strlen(fn)));
3236         }
3237
3238         END_OF_SMB
3239
3240         return offset;
3241 }
3242
3243 static int
3244 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3245 {
3246         guint8 wc;
3247         guint16 cnt=0, bc;
3248         guint32 ofs=0;
3249         smb_info_t *si;
3250         unsigned int fid;
3251
3252         WORD_COUNT;
3253
3254         /* fid */
3255         fid = tvb_get_letohs(tvb, offset);
3256         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
3257         offset += 2;
3258         if (!pinfo->fd->flags.visited) {
3259                 /* remember the FID for the processing of the response */
3260                 si = (smb_info_t *)pinfo->private_data;
3261                 si->sip->extra_info=(void *)fid;
3262         }
3263
3264         /* read count */
3265         cnt = tvb_get_letohs(tvb, offset);
3266         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3267         offset += 2;
3268
3269         /* offset */
3270         ofs = tvb_get_letohl(tvb, offset);
3271         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3272         offset += 4;
3273
3274         if (check_col(pinfo->cinfo, COL_INFO))
3275                 col_append_fstr(pinfo->cinfo, COL_INFO,
3276                                 ", %u byte%s at offset %u", cnt,
3277                                 (cnt == 1) ? "" : "s", ofs);
3278
3279         /* remaining */
3280         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3281         offset += 2;
3282
3283         BYTE_COUNT;
3284
3285         END_OF_SMB
3286
3287         return offset;
3288 }
3289
3290 int
3291 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3292 {
3293         int tvblen;
3294
3295         if(bc>datalen){
3296                 /* We have some initial padding bytes. */
3297                 /* XXX - use the data offset here instead? */
3298                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3299                         TRUE);
3300                 offset += bc-datalen;
3301                 bc = datalen;
3302         }
3303         tvblen = tvb_length_remaining(tvb, offset);
3304         if(bc>tvblen){
3305                 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);
3306                 offset += tvblen;
3307         } else {
3308                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3309                 offset += bc;
3310         }
3311         return offset;
3312 }
3313
3314 static int
3315 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3316     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3317 {
3318         int tvblen;
3319         tvbuff_t *dcerpc_tvb;
3320
3321         if(bc>datalen){
3322                 /* We have some initial padding bytes. */
3323                 /* XXX - use the data offset here instead? */
3324                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3325                         TRUE);
3326                 offset += bc-datalen;
3327                 bc = datalen;
3328         }
3329         tvblen = tvb_length_remaining(tvb, offset);
3330         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3331         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3332         if(bc>tvblen)
3333                 offset += tvblen;
3334         else
3335                 offset += bc;
3336         return offset;
3337 }
3338
3339 /*
3340  * transporting DCERPC over SMB seems to be implemented in various
3341  * ways. We might just assume it can be done by an almost random
3342  * mix of Trans/Read/Write calls
3343  *
3344  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3345  * and let him sort them out
3346  */
3347 static int
3348 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3349     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3350     guint16 datalen, guint32 ofs, guint16 fid)
3351 {
3352         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3353
3354         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3355                 /* dcerpc call */
3356                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3357                     top_tree, offset, bc, datalen, fid);
3358         } else {
3359                 /* ordinary file data */
3360                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3361         }
3362 }
3363
3364 static int
3365 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3366 {
3367         guint16 cnt=0, bc;
3368         guint8 wc;
3369         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3370         int fid=0;
3371
3372         WORD_COUNT;
3373
3374         /* read count */
3375         cnt = tvb_get_letohs(tvb, offset);
3376         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3377         offset += 2;
3378
3379         /* 8 reserved bytes */
3380         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3381         offset += 8;
3382
3383         /* If we have seen the request, then print which FID this refers to */
3384         /* first check if we have seen the request */
3385         if(si->sip != NULL && si->sip->frame_req>0){
3386                 fid=(int)si->sip->extra_info;
3387                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
3388         }
3389
3390         BYTE_COUNT;
3391
3392         /* buffer format */
3393         CHECK_BYTE_COUNT(1);
3394         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3395         COUNT_BYTES(1);
3396
3397         /* data len */
3398         CHECK_BYTE_COUNT(2);
3399         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3400         COUNT_BYTES(2);
3401
3402         /* file data, might be DCERPC on a pipe */
3403         if(bc){
3404                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3405                     top_tree, offset, bc, bc, 0, (guint16) fid);
3406                 bc = 0;
3407         }
3408
3409         END_OF_SMB
3410
3411         return offset;
3412 }
3413
3414 static int
3415 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3416 {
3417         guint16 cnt, bc;
3418         guint8 wc;
3419
3420         WORD_COUNT;
3421
3422         /* read count */
3423         cnt = tvb_get_letohs(tvb, offset);
3424         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3425         offset += 2;
3426
3427         /* 8 reserved bytes */
3428         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3429         offset += 8;
3430
3431         BYTE_COUNT;
3432
3433         /* buffer format */
3434         CHECK_BYTE_COUNT(1);
3435         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3436         COUNT_BYTES(1);
3437
3438         /* data len */
3439         CHECK_BYTE_COUNT(2);
3440         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3441         COUNT_BYTES(2);
3442
3443         END_OF_SMB
3444
3445         return offset;
3446 }
3447
3448
3449 static int
3450 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3451 {
3452         guint32 ofs=0;
3453         guint16 cnt=0, bc, fid=0;
3454         guint8 wc;
3455
3456         WORD_COUNT;
3457
3458         /* fid */
3459         fid = tvb_get_letohs(tvb, offset);
3460         add_fid(tvb, pinfo, tree, offset, 2, fid);
3461         offset += 2;
3462
3463         /* write count */
3464         cnt = tvb_get_letohs(tvb, offset);
3465         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3466         offset += 2;
3467
3468         /* offset */
3469         ofs = tvb_get_letohl(tvb, offset);
3470         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3471         offset += 4;
3472
3473         if (check_col(pinfo->cinfo, COL_INFO))
3474                 col_append_fstr(pinfo->cinfo, COL_INFO,
3475                                 ", %u byte%s at offset %u", cnt,
3476                                 (cnt == 1) ? "" : "s", ofs);
3477
3478         /* remaining */
3479         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3480         offset += 2;
3481
3482         BYTE_COUNT;
3483
3484         /* buffer format */
3485         CHECK_BYTE_COUNT(1);
3486         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3487         COUNT_BYTES(1);
3488
3489         /* data len */
3490         CHECK_BYTE_COUNT(2);
3491         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3492         COUNT_BYTES(2);
3493
3494         /* file data, might be DCERPC on a pipe */
3495         if (bc != 0) {
3496                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3497                     top_tree, offset, bc, bc, ofs, fid);
3498                 bc = 0;
3499         }
3500
3501         END_OF_SMB
3502
3503         return offset;
3504 }
3505
3506 static int
3507 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3508 {
3509         guint8 wc;
3510         guint16 bc, cnt;
3511
3512         WORD_COUNT;
3513
3514         /* write count */
3515         cnt = tvb_get_letohs(tvb, offset);
3516         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3517         offset += 2;
3518
3519         if (check_col(pinfo->cinfo, COL_INFO))
3520                 col_append_fstr(pinfo->cinfo, COL_INFO,
3521                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3522
3523         BYTE_COUNT;
3524
3525         END_OF_SMB
3526
3527         return offset;
3528 }
3529
3530 static int
3531 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3532 {
3533         guint8 wc;
3534         guint16 bc, fid;
3535
3536         WORD_COUNT;
3537
3538         /* fid */
3539         fid = tvb_get_letohs(tvb, offset);
3540         add_fid(tvb, pinfo, tree, offset, 2, fid);
3541         offset += 2;
3542
3543         /* lock count */
3544         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3545         offset += 4;
3546
3547         /* offset */
3548         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3549         offset += 4;
3550
3551         BYTE_COUNT;
3552
3553         END_OF_SMB
3554
3555         return offset;
3556 }
3557
3558 static int
3559 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3560 {
3561         smb_info_t *si = pinfo->private_data;
3562         int fn_len;
3563         const char *fn;
3564         guint8 wc;
3565         guint16 bc;
3566
3567         WORD_COUNT;
3568
3569         /* 2 reserved bytes */
3570         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3571         offset += 2;
3572
3573         /* Creation time */
3574         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3575
3576         BYTE_COUNT;
3577
3578         /* buffer format */
3579         CHECK_BYTE_COUNT(1);
3580         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3581         COUNT_BYTES(1);
3582
3583         /* directory name */
3584         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3585                 FALSE, FALSE, &bc);
3586         if (fn == NULL)
3587                 goto endofcommand;
3588         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3589                 fn);
3590         COUNT_BYTES(fn_len);
3591
3592         if (check_col(pinfo->cinfo, COL_INFO)) {
3593                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3594                     format_text(fn, strlen(fn)));
3595         }
3596
3597         END_OF_SMB
3598
3599         return offset;
3600 }
3601
3602 static int
3603 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3604 {
3605         smb_info_t *si = pinfo->private_data;
3606         int fn_len;
3607         const char *fn;
3608         guint8 wc;
3609         guint16 bc, fid;
3610
3611         WORD_COUNT;
3612
3613         /* fid */
3614         fid = tvb_get_letohs(tvb, offset);
3615         add_fid(tvb, pinfo, tree, offset, 2, fid);
3616         offset += 2;
3617
3618         BYTE_COUNT;
3619
3620         /* buffer format */
3621         CHECK_BYTE_COUNT(1);
3622         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3623         COUNT_BYTES(1);
3624
3625         /* file name */
3626         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3627                 FALSE, FALSE, &bc);
3628         if (fn == NULL)
3629                 goto endofcommand;
3630         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3631                 fn);
3632         COUNT_BYTES(fn_len);
3633
3634         END_OF_SMB
3635
3636         return offset;
3637 }
3638
3639 static const value_string seek_mode_vals[] = {
3640         {0,     "From Start Of File"},
3641         {1,     "From Current Position"},
3642         {2,     "From End Of File"},
3643         {0,     NULL}
3644 };
3645
3646 static int
3647 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3648 {
3649         guint8 wc;
3650         guint16 bc, fid;
3651
3652         WORD_COUNT;
3653
3654         /* fid */
3655         fid = tvb_get_letohs(tvb, offset);
3656         add_fid(tvb, pinfo, tree, offset, 2, fid);
3657         offset += 2;
3658
3659         /* Seek Mode */
3660         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3661         offset += 2;
3662
3663         /* offset */
3664         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3665         offset += 4;
3666
3667         BYTE_COUNT;
3668
3669         END_OF_SMB
3670
3671         return offset;
3672 }
3673
3674 static int
3675 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3676 {
3677         guint8 wc;
3678         guint16 bc;
3679
3680         WORD_COUNT;
3681
3682         /* offset */
3683         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3684         offset += 4;
3685
3686         BYTE_COUNT;
3687
3688         END_OF_SMB
3689
3690         return offset;
3691 }
3692
3693 static int
3694 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3695 {
3696         guint8 wc;
3697         guint16 bc, fid;
3698
3699         WORD_COUNT;
3700
3701         /* fid */
3702         fid = tvb_get_letohs(tvb, offset);
3703         add_fid(tvb, pinfo, tree, offset, 2, fid);
3704         offset += 2;
3705
3706         /* create time */
3707         offset = dissect_smb_datetime(tvb, tree, offset,
3708                 hf_smb_create_time,
3709                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3710
3711         /* access time */
3712         offset = dissect_smb_datetime(tvb, tree, offset,
3713                 hf_smb_access_time,
3714                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3715
3716         /* last write time */
3717         offset = dissect_smb_datetime(tvb, tree, offset,
3718                 hf_smb_last_write_time,
3719                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3720
3721         BYTE_COUNT;
3722
3723         END_OF_SMB
3724
3725         return offset;
3726 }
3727
3728 static int
3729 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3730 {
3731         guint8 wc;
3732         guint16 bc;
3733
3734         WORD_COUNT;
3735
3736         /* create time */
3737         offset = dissect_smb_datetime(tvb, tree, offset,
3738                 hf_smb_create_time,
3739                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3740
3741         /* access time */
3742         offset = dissect_smb_datetime(tvb, tree, offset,
3743                 hf_smb_access_time,
3744                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3745
3746         /* last write time */
3747         offset = dissect_smb_datetime(tvb, tree, offset,
3748                 hf_smb_last_write_time,
3749                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3750
3751         /* data size */
3752         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3753         offset += 4;
3754
3755         /* allocation size */
3756         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3757         offset += 4;
3758
3759         /* File Attributes */
3760         offset = dissect_file_attributes(tvb, tree, offset, 2);
3761
3762         BYTE_COUNT;
3763
3764         END_OF_SMB
3765
3766         return offset;
3767 }
3768
3769 static int
3770 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3771 {
3772         guint8 wc;
3773         guint16 cnt=0;
3774         guint16 bc, fid;
3775
3776         WORD_COUNT;
3777
3778         /* fid */
3779         fid = tvb_get_letohs(tvb, offset);
3780         add_fid(tvb, pinfo, tree, offset, 2, fid);
3781         offset += 2;
3782
3783         /* write count */
3784         cnt = tvb_get_letohs(tvb, offset);
3785         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3786         offset += 2;
3787
3788         /* offset */
3789         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3790         offset += 4;
3791
3792         /* last write time */
3793         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3794
3795         if(wc==12){
3796                 /* 12 reserved bytes */
3797                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3798                 offset += 12;
3799         }
3800
3801         BYTE_COUNT;
3802
3803         /* 1 pad byte */
3804         CHECK_BYTE_COUNT(1);
3805         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3806         COUNT_BYTES(1);
3807
3808         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3809         bc = 0; /* XXX */
3810
3811         END_OF_SMB
3812
3813         return offset;
3814 }
3815
3816 static int
3817 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3818 {
3819         guint8 wc;
3820         guint16 bc;
3821
3822         WORD_COUNT;
3823
3824         /* write count */
3825         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3826         offset += 2;
3827
3828         BYTE_COUNT;
3829
3830         END_OF_SMB
3831
3832         return offset;
3833 }
3834
3835 static int
3836 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3837 {
3838         guint8 wc;
3839         guint16 bc, fid;
3840         guint32 to;
3841
3842         WORD_COUNT;
3843
3844         /* fid */
3845         fid = tvb_get_letohs(tvb, offset);
3846         add_fid(tvb, pinfo, tree, offset, 2, fid);
3847         offset += 2;
3848
3849         /* offset */
3850         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3851         offset += 4;
3852
3853         /* max count */
3854         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3855         offset += 2;
3856
3857         /* min count */
3858         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3859         offset += 2;
3860
3861         /* timeout */
3862         to = tvb_get_letohl(tvb, offset);
3863         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3864         offset += 4;
3865
3866         /* 2 reserved bytes */
3867         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3868         offset += 2;
3869
3870         if(wc==10){
3871                 /* high offset */
3872                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3873                 offset += 4;
3874         }
3875
3876         BYTE_COUNT;
3877
3878         END_OF_SMB
3879
3880         return offset;
3881 }
3882
3883 static int
3884 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3885 {
3886         guint8 wc;
3887         guint16 bc;
3888
3889         WORD_COUNT;
3890
3891         /* units */
3892         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3893         offset += 2;
3894
3895         /* bpu */
3896         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3897         offset += 2;
3898
3899         /* block size */
3900         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3901         offset += 2;
3902
3903         /* free units */
3904         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3905         offset += 2;
3906
3907         /* 2 reserved bytes */
3908         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3909         offset += 2;
3910
3911         BYTE_COUNT;
3912
3913         END_OF_SMB
3914
3915         return offset;
3916 }
3917
3918 static int
3919 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3920 {
3921         guint8 wc;
3922         guint16 bc, fid;
3923
3924         WORD_COUNT;
3925
3926         /* fid */
3927         fid = tvb_get_letohs(tvb, offset);
3928         add_fid(tvb, pinfo, tree, offset, 2, fid);
3929         offset += 2;
3930
3931         /* offset */
3932         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3933         offset += 4;
3934
3935         /* max count */
3936         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3937         offset += 2;
3938
3939         /* min count */
3940         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3941         offset += 2;
3942
3943         /* 6 reserved bytes */
3944         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3945         offset += 6;
3946
3947         BYTE_COUNT;
3948
3949         END_OF_SMB
3950
3951         return offset;
3952 }
3953
3954 static int
3955 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3956 {
3957         guint16 datalen=0, bc;
3958         guint8 wc;
3959
3960         WORD_COUNT;
3961
3962         /* offset */
3963         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3964         offset += 4;
3965
3966         /* count */
3967         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3968         offset += 2;
3969
3970         /* 2 reserved bytes */
3971         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3972         offset += 2;
3973
3974         /* data compaction mode */
3975         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3976         offset += 2;
3977
3978         /* 2 reserved bytes */
3979         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3980         offset += 2;
3981
3982         /* data len */
3983         datalen = tvb_get_letohs(tvb, offset);
3984         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3985         offset += 2;
3986
3987         /* data offset */
3988         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3989         offset += 2;
3990
3991         BYTE_COUNT;
3992
3993         /* file data */
3994         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
3995         bc = 0;
3996
3997         END_OF_SMB
3998
3999         return offset;
4000 }
4001
4002
4003 static const true_false_string tfs_write_mode_write_through = {
4004         "WRITE THROUGH requested",
4005         "Write through not requested"
4006 };
4007 static const true_false_string tfs_write_mode_return_remaining = {
4008         "RETURN REMAINING (pipe/dev) requested",
4009         "DON'T return remaining (pipe/dev)"
4010 };
4011 static const true_false_string tfs_write_mode_raw = {
4012         "Use WriteRawNamedPipe (pipe)",
4013         "DON'T use WriteRawNamedPipe (pipe)"
4014 };
4015 static const true_false_string tfs_write_mode_message_start = {
4016         "This is the START of a MESSAGE (pipe)",
4017         "This is NOT the start of a message (pipe)"
4018 };
4019 static const true_false_string tfs_write_mode_connectionless = {
4020         "CONNECTIONLESS mode requested",
4021         "Connectionless mode NOT requested"
4022 };
4023
4024 #define WRITE_MODE_CONNECTIONLESS       0x0080
4025 #define WRITE_MODE_MESSAGE_START        0x0008
4026 #define WRITE_MODE_RAW                  0x0004
4027 #define WRITE_MODE_RETURN_REMAINING     0x0002
4028 #define WRITE_MODE_WRITE_THROUGH        0x0001
4029
4030 static int
4031 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4032 {
4033         guint16 mask;
4034         proto_item *item = NULL;
4035         proto_tree *tree = NULL;
4036
4037         mask = tvb_get_letohs(tvb, offset);
4038
4039         if(parent_tree){
4040                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4041                         "Write Mode: 0x%04x", mask);
4042                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4043         }
4044
4045         if(bm&WRITE_MODE_CONNECTIONLESS){
4046                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4047                         tvb, offset, 2, mask);
4048         }
4049         if(bm&WRITE_MODE_MESSAGE_START){
4050                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4051                         tvb, offset, 2, mask);
4052         }
4053         if(bm&WRITE_MODE_RAW){
4054                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4055                         tvb, offset, 2, mask);
4056         }
4057         if(bm&WRITE_MODE_RETURN_REMAINING){
4058                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4059                         tvb, offset, 2, mask);
4060         }
4061         if(bm&WRITE_MODE_WRITE_THROUGH){
4062                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4063                         tvb, offset, 2, mask);
4064         }
4065
4066         offset += 2;
4067         return offset;
4068 }
4069
4070 static int
4071 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4072 {
4073         guint32 to;
4074         guint16 datalen=0, bc, fid;
4075         guint8 wc;
4076
4077         WORD_COUNT;
4078
4079         /* fid */
4080         fid = tvb_get_letohs(tvb, offset);
4081         add_fid(tvb, pinfo, tree, offset, 2, fid);
4082         offset += 2;
4083
4084         /* total data length */
4085         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4086         offset += 2;
4087
4088         /* 2 reserved bytes */
4089         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4090         offset += 2;
4091
4092         /* offset */
4093         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4094         offset += 4;
4095
4096         /* timeout */
4097         to = tvb_get_letohl(tvb, offset);
4098         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4099         offset += 4;
4100
4101         /* mode */
4102         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4103
4104         /* 4 reserved bytes */
4105         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4106         offset += 4;
4107
4108         /* data len */
4109         datalen = tvb_get_letohs(tvb, offset);
4110         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4111         offset += 2;
4112
4113         /* data offset */
4114         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4115         offset += 2;
4116
4117         BYTE_COUNT;
4118
4119         /* file data */
4120         /* XXX - use the data offset to determine where the data starts? */
4121         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4122         bc = 0;
4123
4124         END_OF_SMB
4125
4126         return offset;
4127 }
4128
4129 static int
4130 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4131 {
4132         guint8 wc;
4133         guint16 bc;
4134
4135         WORD_COUNT;
4136
4137         /* remaining */
4138         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4139         offset += 2;
4140
4141         BYTE_COUNT;
4142
4143         END_OF_SMB
4144
4145         return offset;
4146 }
4147
4148 static int
4149 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4150 {
4151         guint32 to;
4152         guint16 datalen=0, bc, fid;
4153         guint8 wc;
4154
4155         WORD_COUNT;
4156
4157         /* fid */
4158         fid = tvb_get_letohs(tvb, offset);
4159         add_fid(tvb, pinfo, tree, offset, 2, fid);
4160         offset += 2;
4161
4162         /* total data length */
4163         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4164         offset += 2;
4165
4166         /* 2 reserved bytes */
4167         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4168         offset += 2;
4169
4170         /* offset */
4171         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4172         offset += 4;
4173
4174         /* timeout */
4175         to = tvb_get_letohl(tvb, offset);
4176         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4177         offset += 4;
4178
4179         /* mode */
4180         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4181
4182         /* request mask */
4183         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4184         offset += 4;
4185
4186         /* data len */
4187         datalen = tvb_get_letohs(tvb, offset);
4188         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4189         offset += 2;
4190
4191         /* data offset */
4192         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4193         offset += 2;
4194
4195         BYTE_COUNT;
4196
4197         /* file data */
4198         /* XXX - use the data offset to determine where the data starts? */
4199         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4200         bc = 0;
4201
4202         END_OF_SMB
4203
4204         return offset;
4205 }
4206
4207 static int
4208 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4209 {
4210         guint8 wc;
4211         guint16 bc;
4212
4213         WORD_COUNT;
4214
4215         /* response mask */
4216         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4217         offset += 4;
4218
4219         BYTE_COUNT;
4220
4221         END_OF_SMB
4222
4223         return offset;
4224 }
4225
4226 static int
4227 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4228 {
4229         guint8 wc;
4230         guint16 bc;
4231
4232         WORD_COUNT;
4233
4234         /* sid */
4235         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4236         offset += 2;
4237
4238         BYTE_COUNT;
4239
4240         END_OF_SMB
4241
4242         return offset;
4243 }
4244
4245 static int
4246 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4247     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4248     gboolean has_find_id)
4249 {
4250         proto_item *item = NULL;
4251         proto_tree *tree = NULL;
4252         smb_info_t *si = pinfo->private_data;
4253         int fn_len;
4254         const char *fn;
4255         char fname[11+1];
4256
4257         if(parent_tree){
4258                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4259                         "Resume Key");
4260                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4261         }
4262
4263         /* reserved byte */
4264         CHECK_BYTE_COUNT_SUBR(1);
4265         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4266         COUNT_BYTES_SUBR(1);
4267
4268         /* file name */
4269         fn_len = 11;
4270         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4271                 TRUE, TRUE, bcp);
4272         CHECK_STRING_SUBR(fn);
4273         /* ensure that it's null-terminated */
4274         strncpy(fname, fn, 11);
4275         fname[11] = '\0';
4276         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4277                 fname);
4278         COUNT_BYTES_SUBR(fn_len);
4279
4280         if (has_find_id) {
4281                 CHECK_BYTE_COUNT_SUBR(1);
4282                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4283                 COUNT_BYTES_SUBR(1);
4284
4285                 /* server cookie */
4286                 CHECK_BYTE_COUNT_SUBR(4);
4287                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4288                 COUNT_BYTES_SUBR(4);
4289         } else {
4290                 /* server cookie */
4291                 CHECK_BYTE_COUNT_SUBR(5);
4292                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4293                 COUNT_BYTES_SUBR(5);
4294         }
4295
4296         /* client cookie */
4297         CHECK_BYTE_COUNT_SUBR(4);
4298         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4299         COUNT_BYTES_SUBR(4);
4300
4301         *trunc = FALSE;
4302         return offset;
4303 }
4304
4305 static int
4306 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4307     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4308     gboolean has_find_id)
4309 {
4310         proto_item *item = NULL;
4311         proto_tree *tree = NULL;
4312         smb_info_t *si = pinfo->private_data;
4313         int fn_len;
4314         const char *fn;
4315         char fname[13+1];
4316
4317         if(parent_tree){
4318                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4319                         "Directory Information");
4320                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4321         }
4322
4323         /* resume key */
4324         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4325             trunc, has_find_id);
4326         if (*trunc)
4327                 return offset;
4328
4329         /* File Attributes */
4330         CHECK_BYTE_COUNT_SUBR(1);
4331         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4332         *bcp -= 1;
4333
4334         /* last write time */
4335         CHECK_BYTE_COUNT_SUBR(4);
4336         offset = dissect_smb_datetime(tvb, tree, offset,
4337                 hf_smb_last_write_time,
4338                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4339                 TRUE);
4340         *bcp -= 4;
4341
4342         /* File Size */
4343         CHECK_BYTE_COUNT_SUBR(4);
4344         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4345         COUNT_BYTES_SUBR(4);
4346
4347         /* file name */
4348         fn_len = 13;
4349         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4350                 TRUE, TRUE, bcp);
4351         CHECK_STRING_SUBR(fn);
4352         /* ensure that it's null-terminated */
4353         strncpy(fname, fn, 13);
4354         fname[13] = '\0';
4355         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4356                 fname);
4357         COUNT_BYTES_SUBR(fn_len);
4358
4359         *trunc = FALSE;
4360         return offset;
4361 }
4362
4363
4364 static int
4365 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4366     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4367     gboolean has_find_id)
4368 {
4369         smb_info_t *si = pinfo->private_data;
4370         int fn_len;
4371         const char *fn;
4372         guint16 rkl;
4373         guint8 wc;
4374         guint16 bc;
4375         gboolean trunc;
4376
4377         WORD_COUNT;
4378
4379         /* max count */
4380         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4381         offset += 2;
4382
4383         /* Search Attributes */
4384         offset = dissect_search_attributes(tvb, tree, offset);
4385
4386         BYTE_COUNT;
4387
4388         /* buffer format */
4389         CHECK_BYTE_COUNT(1);
4390         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4391         COUNT_BYTES(1);
4392
4393         /* file name */
4394         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4395                 TRUE, FALSE, &bc);
4396         if (fn == NULL)
4397                 goto endofcommand;
4398         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4399                 fn);
4400         COUNT_BYTES(fn_len);
4401
4402         if (check_col(pinfo->cinfo, COL_INFO)) {
4403                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
4404                     format_text(fn, strlen(fn)));
4405         }
4406
4407         /* buffer format */
4408         CHECK_BYTE_COUNT(1);
4409         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4410         COUNT_BYTES(1);
4411
4412         /* resume key length */
4413         CHECK_BYTE_COUNT(2);
4414         rkl = tvb_get_letohs(tvb, offset);
4415         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4416         COUNT_BYTES(2);
4417
4418         /* resume key */
4419         if(rkl){
4420                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4421                     &bc, &trunc, has_find_id);
4422                 if (trunc)
4423                         goto endofcommand;
4424         }
4425
4426         END_OF_SMB
4427
4428         return offset;
4429 }
4430
4431 static int
4432 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4433     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4434 {
4435         return dissect_search_find_request(tvb, pinfo, tree, offset,
4436             smb_tree, FALSE);
4437 }
4438
4439 static int
4440 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4441     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4442 {
4443         return dissect_search_find_request(tvb, pinfo, tree, offset,
4444             smb_tree, TRUE);
4445 }
4446
4447 static int
4448 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4449     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4450 {
4451         return dissect_search_find_request(tvb, pinfo, tree, offset,
4452             smb_tree, TRUE);
4453 }
4454
4455 static int
4456 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4457     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4458     gboolean has_find_id)
4459 {
4460         guint16 count=0;
4461         guint8 wc;
4462         guint16 bc;
4463         gboolean trunc;
4464
4465         WORD_COUNT;
4466
4467         /* count */
4468         count = tvb_get_letohs(tvb, offset);
4469         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4470         offset += 2;
4471
4472         BYTE_COUNT;
4473
4474         /* buffer format */
4475         CHECK_BYTE_COUNT(1);
4476         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4477         COUNT_BYTES(1);
4478
4479         /* data len */
4480         CHECK_BYTE_COUNT(2);
4481         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4482         COUNT_BYTES(2);
4483
4484         while(count--){
4485                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4486                     &bc, &trunc, has_find_id);
4487                 if (trunc)
4488                         goto endofcommand;
4489         }
4490
4491         END_OF_SMB
4492
4493         return offset;
4494 }
4495
4496 static int
4497 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4498 {
4499         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4500             FALSE);
4501 }
4502
4503 static int
4504 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4505 {
4506         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4507             TRUE);
4508 }
4509
4510 static int
4511 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4512     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4513 {
4514         guint8 wc;
4515         guint16 bc;
4516         guint16 data_len;
4517
4518         WORD_COUNT;
4519
4520         /* reserved */
4521         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4522         offset += 2;
4523
4524         BYTE_COUNT;
4525
4526         /* buffer format */
4527         CHECK_BYTE_COUNT(1);
4528         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4529         COUNT_BYTES(1);
4530
4531         /* data len */
4532         CHECK_BYTE_COUNT(2);
4533         data_len = tvb_get_ntohs(tvb, offset);
4534         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4535         COUNT_BYTES(2);
4536
4537         if (data_len != 0) {
4538                 CHECK_BYTE_COUNT(data_len);
4539                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4540                     data_len, TRUE);
4541                 COUNT_BYTES(data_len);
4542         }
4543
4544         END_OF_SMB
4545
4546         return offset;
4547 }
4548
4549 static const value_string locking_ol_vals[] = {
4550         {0,     "Client is not holding oplock on this file"},
4551         {1,     "Level 2 oplock currently held by client"},
4552         {0, NULL}
4553 };
4554
4555 static const true_false_string tfs_lock_type_large = {
4556         "Large file locking format requested",
4557         "Large file locking format not requested"
4558 };
4559 static const true_false_string tfs_lock_type_cancel = {
4560         "Cancel outstanding lock request",
4561         "Don't cancel outstanding lock request"
4562 };
4563 static const true_false_string tfs_lock_type_change = {
4564         "Change lock type",
4565         "Don't change lock type"
4566 };
4567 static const true_false_string tfs_lock_type_oplock = {
4568         "This is an oplock break notification/response",
4569         "This is not an oplock break notification/response"
4570 };
4571 static const true_false_string tfs_lock_type_shared = {
4572         "This is a shared lock",
4573         "This is an exclusive lock"
4574 };
4575 static int
4576 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4577 {
4578         guint8  wc, cmd=0xff, lt=0;
4579         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4580         guint32 to;
4581         proto_item *litem = NULL;
4582         proto_tree *ltree = NULL;
4583         proto_item *it = NULL;
4584         proto_tree *tr = NULL;
4585         int old_offset = offset;
4586
4587         WORD_COUNT;
4588
4589         /* next smb command */
4590         cmd = tvb_get_guint8(tvb, offset);
4591         if(cmd!=0xff){
4592                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4593         } else {
4594                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4595         }
4596         offset += 1;
4597
4598         /* reserved byte */
4599         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4600         offset += 1;
4601
4602         /* andxoffset */
4603         andxoffset = tvb_get_letohs(tvb, offset);
4604         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4605         offset += 2;
4606
4607         /* fid */
4608         fid = tvb_get_letohs(tvb, offset);
4609         add_fid(tvb, pinfo, tree, offset, 2, fid);
4610         offset += 2;
4611
4612         /* lock type */
4613         lt = tvb_get_guint8(tvb, offset);
4614         if(tree){
4615                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4616                         "Lock Type: 0x%02x", lt);
4617                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4618         }
4619         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4620                 tvb, offset, 1, lt);
4621         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4622                 tvb, offset, 1, lt);
4623         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4624                 tvb, offset, 1, lt);
4625         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4626                 tvb, offset, 1, lt);
4627         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4628                 tvb, offset, 1, lt);
4629         offset += 1;
4630
4631         /* oplock level */
4632         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4633         offset += 1;
4634
4635         /* timeout */
4636         to = tvb_get_letohl(tvb, offset);
4637         if (to == 0)
4638                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4639         else if (to == 0xffffffff)
4640                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4641         else
4642                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4643         offset += 4;
4644
4645         /* number of unlocks */
4646         un = tvb_get_letohs(tvb, offset);
4647         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4648         offset += 2;
4649
4650         /* number of locks */
4651         ln = tvb_get_letohs(tvb, offset);
4652         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4653         offset += 2;
4654
4655         BYTE_COUNT;
4656
4657         /* unlocks */
4658         if(un){
4659                 old_offset = offset;
4660
4661                 it = proto_tree_add_text(tree, tvb, offset, -1,
4662                         "Unlocks");
4663                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4664                 while(un--){
4665                         proto_item *litem = NULL;
4666                         proto_tree *ltree = NULL;
4667                         if(lt&0x10){
4668                                 guint8 buf[8];
4669                                 guint32 val;
4670
4671                                 /* large lock format */
4672                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4673                                         "Unlock");
4674                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4675
4676                                 /* PID */
4677                                 CHECK_BYTE_COUNT(2);
4678                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4679                                 COUNT_BYTES(2);
4680
4681                                 /* 2 reserved bytes */
4682                                 CHECK_BYTE_COUNT(2);
4683                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4684                                 COUNT_BYTES(2);
4685
4686                                 /* offset */
4687                                 CHECK_BYTE_COUNT(8);
4688                                 val=tvb_get_letohl(tvb, offset);
4689                                 buf[3]=(val>>24)&0xff;
4690                                 buf[2]=(val>>16)&0xff;
4691                                 buf[1]=(val>> 8)&0xff;
4692                                 buf[0]=(val    )&0xff;
4693                                 val=tvb_get_letohl(tvb, offset+4);
4694                                 buf[7]=(val>>24)&0xff;
4695                                 buf[6]=(val>>16)&0xff;
4696                                 buf[5]=(val>> 8)&0xff;
4697                                 buf[4]=(val    )&0xff;
4698                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4699                                 COUNT_BYTES(8);
4700
4701                                 /* length */
4702                                 CHECK_BYTE_COUNT(8);
4703                                 val=tvb_get_letohl(tvb, offset);
4704                                 buf[3]=(val>>24)&0xff;
4705                                 buf[2]=(val>>16)&0xff;
4706                                 buf[1]=(val>> 8)&0xff;
4707                                 buf[0]=(val    )&0xff;
4708                                 val=tvb_get_letohl(tvb, offset+4);
4709                                 buf[7]=(val>>24)&0xff;
4710                                 buf[6]=(val>>16)&0xff;
4711                                 buf[5]=(val>> 8)&0xff;
4712                                 buf[4]=(val    )&0xff;
4713                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4714                                 COUNT_BYTES(8);
4715                         } else {
4716                                 /* normal lock format */
4717                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4718                                         "Unlock");
4719                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4720
4721                                 /* PID */
4722                                 CHECK_BYTE_COUNT(2);
4723                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4724                                 COUNT_BYTES(2);
4725
4726                                 /* offset */
4727                                 CHECK_BYTE_COUNT(4);
4728                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4729                                 COUNT_BYTES(4);
4730
4731                                 /* lock count */
4732                                 CHECK_BYTE_COUNT(4);
4733                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4734                                 COUNT_BYTES(4);
4735                         }
4736                 }
4737                 proto_item_set_len(it, offset-old_offset);
4738                 it = NULL;
4739         }
4740
4741         /* locks */
4742         if(ln){
4743                 old_offset = offset;
4744
4745                 it = proto_tree_add_text(tree, tvb, offset, -1,
4746                         "Locks");
4747                 tr = proto_item_add_subtree(it, ett_smb_locks);
4748                 while(ln--){
4749                         proto_item *litem = NULL;
4750                         proto_tree *ltree = NULL;
4751                         if(lt&0x10){
4752                                 guint8 buf[8];
4753                                 guint32 val;
4754
4755                                 /* large lock format */
4756                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4757                                         "Lock");
4758                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4759
4760                                 /* PID */
4761                                 CHECK_BYTE_COUNT(2);
4762                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4763                                 COUNT_BYTES(2);
4764
4765                                 /* 2 reserved bytes */
4766                                 CHECK_BYTE_COUNT(2);
4767                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4768                                 COUNT_BYTES(2);
4769
4770                                 /* offset */
4771                                 CHECK_BYTE_COUNT(8);
4772                                 val=tvb_get_letohl(tvb, offset);
4773                                 buf[3]=(val    )&0xff;
4774                                 buf[2]=(val>> 8)&0xff;
4775                                 buf[1]=(val>>16)&0xff;
4776                                 buf[0]=(val>>24)&0xff;
4777                                 val=tvb_get_letohl(tvb, offset+4);
4778                                 buf[7]=(val    )&0xff;
4779                                 buf[6]=(val>> 8)&0xff;
4780                                 buf[5]=(val>>16)&0xff;
4781                                 buf[4]=(val>>24)&0xff;
4782                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4783                                 COUNT_BYTES(8);
4784
4785                                 /* length */
4786                                 CHECK_BYTE_COUNT(8);
4787                                 val=tvb_get_letohl(tvb, offset);
4788                                 buf[3]=(val    )&0xff;
4789                                 buf[2]=(val>> 8)&0xff;
4790                                 buf[1]=(val>>16)&0xff;
4791                                 buf[0]=(val>>24)&0xff;
4792                                 val=tvb_get_letohl(tvb, offset+4);
4793                                 buf[7]=(val    )&0xff;
4794                                 buf[6]=(val>> 8)&0xff;
4795                                 buf[5]=(val>>16)&0xff;
4796                                 buf[4]=(val>>24)&0xff;
4797                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4798                                 COUNT_BYTES(8);
4799                         } else {
4800                                 /* normal lock format */
4801                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4802                                         "Unlock");
4803                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4804
4805                                 /* PID */
4806                                 CHECK_BYTE_COUNT(2);
4807                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4808                                 COUNT_BYTES(2);
4809
4810                                 /* offset */
4811                                 CHECK_BYTE_COUNT(4);
4812                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4813                                 COUNT_BYTES(4);
4814
4815                                 /* lock count */
4816                                 CHECK_BYTE_COUNT(4);
4817                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4818                                 COUNT_BYTES(4);
4819                         }
4820                 }
4821                 proto_item_set_len(it, offset-old_offset);
4822                 it = NULL;
4823         }
4824
4825         END_OF_SMB
4826
4827         if (it != NULL) {
4828                 /*
4829                  * We ran out of byte count in the middle of dissecting
4830                  * the locks or the unlocks; set the site of the item
4831                  * we were dissecting.
4832                  */
4833                 proto_item_set_len(it, offset-old_offset);
4834         }
4835
4836         /* call AndXCommand (if there are any) */
4837         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4838
4839         return offset;
4840 }
4841
4842 static int
4843 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4844 {
4845         guint8  wc, cmd=0xff;
4846         guint16 andxoffset=0;
4847         guint16 bc;
4848
4849         WORD_COUNT;
4850
4851         /* next smb command */
4852         cmd = tvb_get_guint8(tvb, offset);
4853         if(cmd!=0xff){
4854                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4855         } else {
4856                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4857         }
4858         offset += 1;
4859
4860         /* reserved byte */
4861         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4862         offset += 1;
4863
4864         /* andxoffset */
4865         andxoffset = tvb_get_letohs(tvb, offset);
4866         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4867         offset += 2;
4868
4869         BYTE_COUNT;
4870
4871         END_OF_SMB
4872
4873         /* call AndXCommand (if there are any) */
4874         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4875
4876         return offset;
4877 }
4878
4879
4880 static const value_string oa_open_vals[] = {
4881         { 0,            "No action taken?"},
4882         { 1,            "The file existed and was opened"},
4883         { 2,            "The file did not exist but was created"},
4884         { 3,            "The file existed and was truncated"},
4885         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4886         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4887         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4888         {0,     NULL}
4889 };
4890 static const true_false_string tfs_oa_lock = {
4891         "File is currently opened only by this user",
4892         "File is opened by another user (or mode not supported by server)"
4893 };
4894 static int
4895 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4896 {
4897         guint16 mask;
4898         proto_item *item = NULL;
4899         proto_tree *tree = NULL;
4900
4901         mask = tvb_get_letohs(tvb, offset);
4902
4903         if(parent_tree){
4904                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4905                         "Action: 0x%04x", mask);
4906                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4907         }
4908
4909         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4910                 tvb, offset, 2, mask);
4911         proto_tree_add_uint(tree, hf_smb_open_action_open,
4912                 tvb, offset, 2, mask);
4913
4914         offset += 2;
4915
4916         return offset;
4917 }
4918
4919 static const true_false_string tfs_open_flags_add_info = {
4920         "Additional information requested",
4921         "Additional information not requested"
4922 };
4923 static const true_false_string tfs_open_flags_ex_oplock = {
4924         "Exclusive oplock requested",
4925         "Exclusive oplock not requested"
4926 };
4927 static const true_false_string tfs_open_flags_batch_oplock = {
4928         "Batch oplock requested",
4929         "Batch oplock not requested"
4930 };
4931 static const true_false_string tfs_open_flags_ealen = {
4932         "Total length of EAs requested",
4933         "Total length of EAs not requested"
4934 };
4935 static int
4936 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4937 {
4938         guint16 mask;
4939         proto_item *item = NULL;
4940         proto_tree *tree = NULL;
4941
4942         mask = tvb_get_letohs(tvb, offset);
4943
4944         if(parent_tree){
4945                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4946                         "Flags: 0x%04x", mask);
4947                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4948         }
4949
4950         if(bm&0x0001){
4951                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4952                         tvb, offset, 2, mask);
4953         }
4954         if(bm&0x0002){
4955                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4956                         tvb, offset, 2, mask);
4957         }
4958         if(bm&0x0004){
4959                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4960                         tvb, offset, 2, mask);
4961         }
4962         if(bm&0x0008){
4963                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4964                         tvb, offset, 2, mask);
4965         }
4966
4967         offset += 2;
4968
4969         return offset;
4970 }
4971
4972 static const value_string filetype_vals[] = {
4973         { 0,            "Disk file or directory"},
4974         { 1,            "Named pipe in byte mode"},
4975         { 2,            "Named pipe in message mode"},
4976         { 3,            "Spooled printer"},
4977         {0, NULL}
4978 };
4979 static int
4980 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4981 {
4982         guint8  wc, cmd=0xff;
4983         guint16 andxoffset=0, bc;
4984         smb_info_t *si = pinfo->private_data;
4985         int fn_len;
4986         const char *fn;
4987
4988         WORD_COUNT;
4989
4990         /* next smb command */
4991         cmd = tvb_get_guint8(tvb, offset);
4992         if(cmd!=0xff){
4993                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4994         } else {
4995                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4996         }
4997         offset += 1;
4998
4999         /* reserved byte */
5000         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5001         offset += 1;
5002
5003         /* andxoffset */
5004         andxoffset = tvb_get_letohs(tvb, offset);
5005         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5006         offset += 2;
5007
5008         /* open flags */
5009         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5010
5011         /* desired access */
5012         offset = dissect_access(tvb, tree, offset, "Desired");
5013
5014         /* Search Attributes */
5015         offset = dissect_search_attributes(tvb, tree, offset);
5016
5017         /* File Attributes */
5018         offset = dissect_file_attributes(tvb, tree, offset, 2);
5019
5020         /* creation time */
5021         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5022
5023         /* open function */
5024         offset = dissect_open_function(tvb, tree, offset);
5025
5026         /* allocation size */
5027         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5028         offset += 4;
5029
5030         /* 8 reserved bytes */
5031         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5032         offset += 8;
5033
5034         BYTE_COUNT;
5035
5036         /* file name */
5037         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5038                 FALSE, FALSE, &bc);
5039         if (fn == NULL)
5040                 goto endofcommand;
5041         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5042                 fn);
5043         COUNT_BYTES(fn_len);
5044
5045         if (check_col(pinfo->cinfo, COL_INFO)) {
5046                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
5047                     format_text(fn, strlen(fn)));
5048         }
5049
5050         END_OF_SMB
5051
5052         /* call AndXCommand (if there are any) */
5053         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5054
5055         return offset;
5056 }
5057
5058 static const true_false_string tfs_ipc_state_nonblocking = {
5059         "Reads/writes return immediately if no data available",
5060         "Reads/writes block if no data available"
5061 };
5062 static const value_string ipc_state_endpoint_vals[] = {
5063         { 0,            "Consumer end of pipe"},
5064         { 1,            "Server end of pipe"},
5065         {0,     NULL}
5066 };
5067 static const value_string ipc_state_pipe_type_vals[] = {
5068         { 0,            "Byte stream pipe"},
5069         { 1,            "Message pipe"},
5070         {0,     NULL}
5071 };
5072 static const value_string ipc_state_read_mode_vals[] = {
5073         { 0,            "Read pipe as a byte stream"},
5074         { 1,            "Read messages from pipe"},
5075         {0,     NULL}
5076 };
5077
5078 int
5079 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5080     gboolean setstate)
5081 {
5082         guint16 mask;
5083         proto_item *item = NULL;
5084         proto_tree *tree = NULL;
5085
5086         mask = tvb_get_letohs(tvb, offset);
5087
5088         if(parent_tree){
5089                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5090                         "IPC State: 0x%04x", mask);
5091                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5092         }
5093
5094         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5095                 tvb, offset, 2, mask);
5096         if (!setstate) {
5097                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5098                         tvb, offset, 2, mask);
5099                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5100                         tvb, offset, 2, mask);
5101         }
5102         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5103                 tvb, offset, 2, mask);
5104         if (!setstate) {
5105                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5106                         tvb, offset, 2, mask);
5107         }
5108
5109         offset += 2;
5110
5111         return offset;
5112 }
5113
5114 static int
5115 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5116 {
5117         guint8  wc, cmd=0xff;
5118         guint16 andxoffset=0, bc;
5119         guint16 fid;
5120
5121         WORD_COUNT;
5122
5123         /* next smb command */
5124         cmd = tvb_get_guint8(tvb, offset);
5125         if(cmd!=0xff){
5126                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5127         } else {
5128                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5129         }
5130         offset += 1;
5131
5132         /* reserved byte */
5133         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5134         offset += 1;
5135
5136         /* andxoffset */
5137         andxoffset = tvb_get_letohs(tvb, offset);
5138         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5139         offset += 2;
5140
5141         /* fid */
5142         fid = tvb_get_letohs(tvb, offset);
5143         add_fid(tvb, pinfo, tree, offset, 2, fid);
5144         offset += 2;
5145
5146         /* File Attributes */
5147         offset = dissect_file_attributes(tvb, tree, offset, 2);
5148
5149         /* last write time */
5150         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5151
5152         /* File Size */
5153         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5154         offset += 4;
5155
5156         /* granted access */
5157         offset = dissect_access(tvb, tree, offset, "Granted");
5158
5159         /* File Type */
5160         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5161         offset += 2;
5162
5163         /* IPC State */
5164         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5165
5166         /* open_action */
5167         offset = dissect_open_action(tvb, tree, offset);
5168
5169         /* server fid */
5170         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5171         offset += 4;
5172
5173         /* 2 reserved bytes */
5174         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5175         offset += 2;
5176
5177         BYTE_COUNT;
5178
5179         END_OF_SMB
5180
5181         /* call AndXCommand (if there are any) */
5182         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5183
5184         return offset;
5185 }
5186
5187 static int
5188 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5189 {
5190         guint8  wc, cmd=0xff;
5191         guint16 andxoffset=0, bc, maxcnt_low;
5192         guint32 maxcnt_high;
5193         guint32 maxcnt=0;
5194         guint32 ofs = 0;
5195         smb_info_t *si;
5196         unsigned int fid;
5197
5198         WORD_COUNT;
5199
5200         /* next smb command */
5201         cmd = tvb_get_guint8(tvb, offset);
5202         if(cmd!=0xff){
5203                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5204         } else {
5205                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5206         }
5207         offset += 1;
5208
5209         /* reserved byte */
5210         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5211         offset += 1;
5212
5213         /* andxoffset */
5214         andxoffset = tvb_get_letohs(tvb, offset);
5215         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5216         offset += 2;
5217
5218         /* fid */
5219         fid = tvb_get_letohs(tvb, offset);
5220         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5221         offset += 2;
5222         if (!pinfo->fd->flags.visited) {
5223                 /* remember the FID for the processing of the response */
5224                 si = (smb_info_t *)pinfo->private_data;
5225                 si->sip->extra_info=(void *)fid;
5226         }
5227
5228         /* offset */
5229         ofs = tvb_get_letohl(tvb, offset);
5230         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5231         offset += 4;
5232
5233         /* max count low */
5234         maxcnt_low = tvb_get_letohs(tvb, offset);
5235         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5236         offset += 2;
5237
5238         /* min count */
5239         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5240         offset += 2;
5241
5242         /*
5243          * max count high
5244          *
5245          * XXX - we should really only do this in case we have seen
5246          * LARGE FILE being negotiated.  Unfortunately, we might not
5247          * have seen the negotiation phase in the capture....
5248          *
5249          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5250          * it's 32 bits, but the description says "High 16 bits of
5251          * MaxCount if CAP_LARGE_READX".
5252          *
5253          * The SMB File Sharing Protocol Extensions Version 2.0,
5254          * Document Version 3.3 spec doesn't speak of an extra 16
5255          * bits in max count, but it does show a 32-bit timeout
5256          * after the min count field.
5257          *
5258          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5259          * high count and a 16-bit reserved field.
5260          *
5261          * We fetch and display it as 32 bits.
5262          * 
5263          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5264          * bytes and we just ignore it.
5265          */
5266         maxcnt_high = tvb_get_letohl(tvb, offset);
5267         if(maxcnt_high==0xffffffff){
5268                 maxcnt_high=0;
5269         } else {
5270                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5271         }
5272
5273         offset += 4;
5274
5275         maxcnt=maxcnt_high;
5276         maxcnt=(maxcnt<<16)|maxcnt_low;
5277
5278         if (check_col(pinfo->cinfo, COL_INFO))
5279                 col_append_fstr(pinfo->cinfo, COL_INFO,
5280                                 ", %u byte%s at offset %u", maxcnt,
5281                                 (maxcnt == 1) ? "" : "s", ofs);
5282
5283         /* remaining */
5284         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5285         offset += 2;
5286
5287         if(wc==12){
5288                 /* high offset */
5289                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5290                 offset += 4;
5291         }
5292
5293         BYTE_COUNT;
5294
5295         END_OF_SMB
5296
5297         /* call AndXCommand (if there are any) */
5298         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5299
5300         return offset;
5301 }
5302
5303 static int
5304 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5305 {
5306         guint8  wc, cmd=0xff;
5307         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
5308         guint32 datalen=0, datalen_high;
5309         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5310         int fid=0;
5311
5312         WORD_COUNT;
5313
5314         /* next smb command */
5315         cmd = tvb_get_guint8(tvb, offset);
5316         if(cmd!=0xff){
5317                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5318         } else {
5319                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5320         }
5321         offset += 1;
5322
5323         /* reserved byte */
5324         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5325         offset += 1;
5326
5327         /* andxoffset */
5328         andxoffset = tvb_get_letohs(tvb, offset);
5329         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5330         offset += 2;
5331
5332         /* If we have seen the request, then print which FID this refers to */
5333         /* first check if we have seen the request */
5334         if(si->sip != NULL && si->sip->frame_req>0){
5335                 fid=(int)si->sip->extra_info;
5336                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
5337         }
5338
5339         /* remaining */
5340         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5341         offset += 2;
5342
5343         /* data compaction mode */
5344         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5345         offset += 2;
5346
5347         /* 2 reserved bytes */
5348         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5349         offset += 2;
5350
5351         /* data len low */
5352         datalen_low = tvb_get_letohs(tvb, offset);
5353         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5354         offset += 2;
5355
5356         /* data offset */
5357         dataoffset=tvb_get_letohs(tvb, offset);
5358         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5359         offset += 2;
5360
5361         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5362         /* data length high */
5363         datalen_high = tvb_get_letohl(tvb, offset);
5364         if(datalen_high==0xffffffff){
5365                 datalen_high=0;
5366         } else {
5367                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
5368         }
5369         offset += 4;
5370
5371         datalen=datalen_high;
5372         datalen=(datalen<<16)|datalen_low;
5373
5374
5375         if (check_col(pinfo->cinfo, COL_INFO))
5376                 col_append_fstr(pinfo->cinfo, COL_INFO,
5377                                 ", %u byte%s", datalen,
5378                                 (datalen == 1) ? "" : "s");
5379
5380
5381         /* 6 reserved bytes */
5382         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
5383         offset += 6;
5384
5385         BYTE_COUNT;
5386
5387         /* file data, might be DCERPC on a pipe */
5388         if(bc){
5389                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5390                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5391                 bc = 0;
5392         }
5393
5394         END_OF_SMB
5395
5396         /* call AndXCommand (if there are any) */
5397         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5398
5399         return offset;
5400 }
5401
5402 static int
5403 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5404 {
5405         guint32 ofs=0;
5406         guint8  wc, cmd=0xff;
5407         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5408         guint32 datalen=0;
5409         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5410         unsigned int fid=0;
5411         guint16 mode = 0;
5412
5413         WORD_COUNT;
5414
5415         /* next smb command */
5416         cmd = tvb_get_guint8(tvb, offset);
5417         if(cmd!=0xff){
5418                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5419         } else {
5420                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5421         }
5422         offset += 1;
5423
5424         /* reserved byte */
5425         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5426         offset += 1;
5427
5428         /* andxoffset */
5429         andxoffset = tvb_get_letohs(tvb, offset);
5430         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5431         offset += 2;
5432
5433         /* fid */
5434         fid = tvb_get_letohs(tvb, offset);
5435         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5436         offset += 2;
5437         if (!pinfo->fd->flags.visited) {
5438                 /* remember the FID for the processing of the response */
5439                 si->sip->extra_info=(void *)fid;
5440         }
5441
5442         /* offset */
5443         ofs = tvb_get_letohl(tvb, offset);
5444         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5445         offset += 4;
5446
5447         /* reserved */
5448         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5449         offset += 4;
5450
5451         /* mode */
5452         mode = tvb_get_letohs(tvb, offset);
5453         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5454
5455         /* remaining */
5456         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5457         offset += 2;
5458
5459         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5460         /* data length high */
5461         datalen_high = tvb_get_letohs(tvb, offset);
5462         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5463         offset += 2;
5464
5465         /* data len low */
5466         datalen_low = tvb_get_letohs(tvb, offset);
5467         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5468         offset += 2;
5469
5470         datalen=datalen_high;
5471         datalen=(datalen<<16)|datalen_low;
5472
5473         /* data offset */
5474         dataoffset=tvb_get_letohs(tvb, offset);
5475         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5476         offset += 2;
5477
5478         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5479         if (check_col(pinfo->cinfo, COL_INFO))
5480                 col_append_fstr(pinfo->cinfo, COL_INFO,
5481                                 ", %u byte%s at offset %u", datalen,
5482                                 (datalen == 1) ? "" : "s", ofs);
5483
5484         if(wc==14){
5485                 /* high offset */
5486                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5487                 offset += 4;
5488         }
5489
5490         BYTE_COUNT;
5491
5492         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5493            the first two bytes of the payload is the length of the data.
5494            Assume that all WriteAndX PDUs that have MESSAGE_START set to
5495            be over the IPC$ share and thus they all transport DCERPC.
5496            (if we didnt already know that from the TreeConnect call)
5497         */
5498         if(mode&WRITE_MODE_MESSAGE_START){
5499                 if(mode&WRITE_MODE_RAW){
5500                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5501                         offset += 2;
5502                         dataoffset += 2;
5503                         bc -= 2;
5504                         datalen -= 2;
5505                 }
5506                 if(!pinfo->fd->flags.visited){
5507                         /* In case we did not see the TreeConnect call,
5508                            store this TID here as well as a IPC TID 
5509                            so we know that future Read/Writes to this 
5510                            TID is (probably) DCERPC.
5511                         */
5512                         if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5513                                 g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5514                         }
5515                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5516                 }
5517                 if(si->sip){
5518                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5519                 }
5520         }
5521
5522         /* file data, might be DCERPC on a pipe */
5523         if (bc != 0) {
5524                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5525                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5526                 bc = 0;
5527         }
5528
5529         END_OF_SMB
5530
5531         /* call AndXCommand (if there are any) */
5532         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5533
5534         return offset;
5535 }
5536
5537 static int
5538 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5539 {
5540         guint8  wc, cmd=0xff;
5541         guint16 andxoffset=0, bc, count_low, count_high;
5542         guint32 count=0;
5543         smb_info_t *si;
5544
5545         WORD_COUNT;
5546
5547         /* next smb command */
5548         cmd = tvb_get_guint8(tvb, offset);
5549         if(cmd!=0xff){
5550                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5551         } else {
5552                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5553         }
5554         offset += 1;
5555
5556         /* reserved byte */
5557         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5558         offset += 1;
5559
5560         /* andxoffset */
5561         andxoffset = tvb_get_letohs(tvb, offset);
5562         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5563         offset += 2;
5564
5565         /* If we have seen the request, then print which FID this refers to */
5566         si = (smb_info_t *)pinfo->private_data;
5567         /* first check if we have seen the request */
5568         if(si->sip != NULL && si->sip->frame_req>0){
5569                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) GPOINTER_TO_UINT(si->sip->extra_info));
5570         }
5571
5572         /* write count low */
5573         count_low = tvb_get_letohs(tvb, offset);
5574         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5575         offset += 2;
5576
5577         /* remaining */
5578         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5579         offset += 2;
5580
5581         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5582         /* write count high */
5583         count_high = tvb_get_letohs(tvb, offset);
5584         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5585         offset += 2;
5586
5587         count=count_high;
5588         count=(count<<16)|count_low;
5589
5590         if (check_col(pinfo->cinfo, COL_INFO))
5591                 col_append_fstr(pinfo->cinfo, COL_INFO,
5592                                 ", %u byte%s", count,
5593                                 (count == 1) ? "" : "s");
5594
5595         /* 2 reserved bytes */
5596         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5597         offset += 2;
5598
5599         BYTE_COUNT;
5600
5601         END_OF_SMB
5602
5603         /* call AndXCommand (if there are any) */
5604         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5605
5606         return offset;
5607 }
5608
5609
5610 static const true_false_string tfs_setup_action_guest = {
5611         "Logged in as GUEST",
5612         "Not logged in as GUEST"
5613 };
5614 static int
5615 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5616 {
5617         guint16 mask;
5618         proto_item *item = NULL;
5619         proto_tree *tree = NULL;
5620
5621         mask = tvb_get_letohs(tvb, offset);
5622
5623         if(parent_tree){
5624                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5625                         "Action: 0x%04x", mask);
5626                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5627         }
5628
5629         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5630                 tvb, offset, 2, mask);
5631
5632         offset += 2;
5633
5634         return offset;
5635 }
5636
5637
5638 static int
5639 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5640 {
5641         guint8  wc, cmd=0xff;
5642         guint16 bc;
5643         guint16 andxoffset=0;
5644         smb_info_t *si = pinfo->private_data;
5645         int an_len;
5646         const char *an;
5647         int dn_len;
5648         const char *dn;
5649         guint16 pwlen=0;
5650         guint16 sbloblen=0, sbloblen_short;
5651         guint16 apwlen=0, upwlen=0;
5652         gboolean unicodeflag;
5653
5654         WORD_COUNT;
5655
5656         /* next smb command */
5657         cmd = tvb_get_guint8(tvb, offset);
5658         if(cmd!=0xff){
5659                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5660         } else {
5661                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5662         }
5663         offset += 1;
5664
5665         /* reserved byte */
5666         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5667         offset += 1;
5668
5669         /* andxoffset */
5670         andxoffset = tvb_get_letohs(tvb, offset);
5671         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5672         offset += 2;
5673
5674         /* Maximum Buffer Size */
5675         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5676         offset += 2;
5677
5678         /* Maximum Multiplex Count */
5679         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5680         offset += 2;
5681
5682         /* VC Number */
5683         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5684         offset += 2;
5685
5686         /* session key */
5687         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5688         offset += 4;
5689
5690         switch (wc) {
5691         case 10:
5692                 /* password length, ASCII*/
5693                 pwlen = tvb_get_letohs(tvb, offset);
5694                 proto_tree_add_uint(tree, hf_smb_password_len,
5695                         tvb, offset, 2, pwlen);
5696                 offset += 2;
5697
5698                 /* 4 reserved bytes */
5699                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5700                 offset += 4;
5701
5702                 break;
5703
5704         case 12:
5705                 /* security blob length */
5706                 sbloblen = tvb_get_letohs(tvb, offset);
5707                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5708                 offset += 2;
5709
5710                 /* 4 reserved bytes */
5711                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5712                 offset += 4;
5713
5714                 /* capabilities */
5715                 dissect_negprot_capabilities(tvb, tree, offset);
5716                 offset += 4;
5717
5718                 break;
5719
5720         case 13:
5721                 /* password length, ANSI*/
5722                 apwlen = tvb_get_letohs(tvb, offset);
5723                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5724                         tvb, offset, 2, apwlen);
5725                 offset += 2;
5726
5727                 /* password length, Unicode*/
5728                 upwlen = tvb_get_letohs(tvb, offset);
5729                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5730                         tvb, offset, 2, upwlen);
5731                 offset += 2;
5732
5733                 /* 4 reserved bytes */
5734                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5735                 offset += 4;
5736
5737                 /* capabilities */
5738                 dissect_negprot_capabilities(tvb, tree, offset);
5739                 offset += 4;
5740
5741                 break;
5742         }
5743
5744         BYTE_COUNT;
5745
5746         if (wc==12) {
5747                 proto_item *blob_item;
5748
5749                 /* security blob */
5750                 /* If it runs past the end of the captured data, don't
5751                  * try to put all of it into the protocol tree as the
5752                  * raw security blob; we might get an exception on 
5753                  * short frames and then we will not see anything at all
5754                  * of the security blob.
5755                  */
5756                 sbloblen_short = sbloblen;
5757                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
5758                         sbloblen_short=tvb_length_remaining(tvb,offset);
5759                 }
5760                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5761                                                 tvb, offset, sbloblen_short,
5762                                                 TRUE);
5763
5764                 /* As an optimization, because Windows is perverse,
5765                    we check to see if NTLMSSP is the first part of the 
5766                    blob, and if so, call the NTLMSSP dissector,
5767                    otherwise we call the GSS-API dissector. This is because
5768                    Windows can request RAW NTLMSSP, but will happily handle
5769                    a client that wraps NTLMSSP in SPNEGO
5770                 */
5771
5772                 if(sbloblen){
5773                         tvbuff_t *blob_tvb;
5774                         proto_tree *blob_tree;
5775
5776                         blob_tree = proto_item_add_subtree(blob_item, 
5777                                                            ett_smb_secblob);
5778                         CHECK_BYTE_COUNT(sbloblen);
5779
5780                         /*
5781                          * Set the reported length of this to the reported
5782                          * length of the blob, rather than the amount of
5783                          * data available from the blob, so that we'll
5784                          * throw the right exception if it's too short.
5785                          */
5786                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
5787                                                   sbloblen);
5788
5789                         if (si && si->ct && si->ct->raw_ntlmssp &&
5790                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
5791                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5792                                          blob_tree);
5793
5794                         }
5795                         else {
5796                           call_dissector(gssapi_handle, blob_tvb, 
5797                                          pinfo, blob_tree);
5798                         }
5799
5800                         COUNT_BYTES(sbloblen);
5801                 }
5802
5803                 /* OS
5804                  * Eventhough this field should honour the unicode flag
5805                  * some ms clients gets this wrong.
5806                  * At least XP SP1 sends this in ASCII
5807                  * even when the unicode flag is on.
5808                  * Test if the first three bytes are "Win"
5809                  * and if so just override the flag.
5810                  */
5811                 unicodeflag=si->unicode;
5812                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
5813                         unicodeflag=FALSE;
5814                 }
5815                 an = get_unicode_or_ascii_string(tvb, &offset,
5816                         unicodeflag, &an_len, FALSE, FALSE, &bc);
5817                 if (an == NULL)
5818                         goto endofcommand;
5819                 proto_tree_add_string(tree, hf_smb_os, tvb,
5820                         offset, an_len, an);
5821                 COUNT_BYTES(an_len);
5822
5823                 /* LANMAN */
5824                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5825                  * padding/null string/whatever in front of this. W2K doesn't
5826                  * appear to. I suspect that's a bug that got fixed; I also
5827                  * suspect that, in practice, nobody ever looks at that field
5828                  * because the bug didn't appear to get fixed until NT 5.0....
5829                  *
5830                  * Eventhough this field should honour the unicode flag
5831                  * some ms clients gets this wrong.
5832                  * At least XP SP1 sends this in ASCII
5833                  * even when the unicode flag is on.
5834                  * Test if the first three bytes are "Win"
5835                  * and if so just override the flag.
5836                  */
5837                 unicodeflag=si->unicode;
5838                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
5839                         unicodeflag=FALSE;
5840                 }
5841                 an = get_unicode_or_ascii_string(tvb, &offset,
5842                         unicodeflag, &an_len, FALSE, FALSE, &bc);
5843                 if (an == NULL)
5844                         goto endofcommand;
5845                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5846                         offset, an_len, an);
5847                 COUNT_BYTES(an_len);
5848
5849                 /* Primary domain */
5850                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5851                  * byte in front of this, at least if all the strings are
5852                  * ASCII and the account name is empty. Another bug?
5853                  */
5854                 dn = get_unicode_or_ascii_string(tvb, &offset,
5855                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5856                 if (dn == NULL)
5857                         goto endofcommand;
5858                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5859                         offset, dn_len, dn);
5860                 COUNT_BYTES(dn_len);
5861         } else {
5862                 switch (wc) {
5863
5864                 case 10:
5865                         if(pwlen){
5866                                 /* password, ASCII */
5867                                 CHECK_BYTE_COUNT(pwlen);
5868                                 proto_tree_add_item(tree, hf_smb_password,
5869                                         tvb, offset, pwlen, TRUE);
5870                                 COUNT_BYTES(pwlen);
5871                         }
5872
5873                         break;
5874
5875                 case 13:
5876                         if(apwlen){
5877                                 /* password, ANSI */
5878                                 CHECK_BYTE_COUNT(apwlen);
5879                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5880                                         tvb, offset, apwlen, TRUE);
5881                                 COUNT_BYTES(apwlen);
5882                         }
5883
5884                         if(upwlen){
5885                                 proto_item *item;
5886
5887                                 /* password, Unicode */
5888                                 CHECK_BYTE_COUNT(upwlen);
5889                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5890                                         tvb, offset, upwlen, TRUE);
5891
5892                                 if (upwlen > 24) {
5893                                         proto_tree *subtree;
5894
5895                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5896
5897                                         dissect_ntlmv2_response(
5898                                                 tvb, subtree, offset, upwlen);
5899                                 }
5900
5901                                 COUNT_BYTES(upwlen);
5902                         }
5903
5904                         break;
5905                 }
5906
5907                 /* Account Name */
5908                 an = get_unicode_or_ascii_string(tvb, &offset,
5909                         si->unicode, &an_len, FALSE, FALSE, &bc);
5910                 if (an == NULL)
5911                         goto endofcommand;
5912                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5913                         an);
5914                 COUNT_BYTES(an_len);
5915
5916                 /* Primary domain */
5917                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5918                  * byte in front of this, at least if all the strings are
5919                  * ASCII and the account name is empty. Another bug?
5920                  */
5921                 dn = get_unicode_or_ascii_string(tvb, &offset,
5922                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5923                 if (dn == NULL)
5924                         goto endofcommand;
5925                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5926                         offset, dn_len, dn);
5927                 COUNT_BYTES(dn_len);
5928
5929                 if (check_col(pinfo->cinfo, COL_INFO)) {
5930                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5931
5932                         if (!dn[0] && !an[0])
5933                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5934                                                 "anonymous");
5935                         else
5936                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5937                                                 "%s\\%s",
5938                                                 format_text(dn, strlen(dn)),
5939                                                 format_text(an, strlen(an)));
5940                 }
5941
5942                 /* OS */
5943                 an = get_unicode_or_ascii_string(tvb, &offset,
5944                         si->unicode, &an_len, FALSE, FALSE, &bc);
5945                 if (an == NULL)
5946                         goto endofcommand;
5947                 proto_tree_add_string(tree, hf_smb_os, tvb,
5948                         offset, an_len, an);
5949                 COUNT_BYTES(an_len);
5950
5951                 /* LANMAN */
5952                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5953                  * padding/null string/whatever in front of this. W2K doesn't
5954                  * appear to. I suspect that's a bug that got fixed; I also
5955                  * suspect that, in practice, nobody ever looks at that field
5956                  * because the bug didn't appear to get fixed until NT 5.0....
5957                  */
5958                 an = get_unicode_or_ascii_string(tvb, &offset,
5959                         si->unicode, &an_len, FALSE, FALSE, &bc);
5960                 if (an == NULL)
5961                         goto endofcommand;
5962                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5963                         offset, an_len, an);
5964                 COUNT_BYTES(an_len);
5965         }
5966
5967         END_OF_SMB
5968
5969         /* call AndXCommand (if there are any) */
5970         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5971
5972         return offset;
5973 }
5974
5975 static int
5976 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5977 {
5978         guint8  wc, cmd=0xff;
5979         guint16 andxoffset=0, bc;
5980         guint16 sbloblen=0;
5981         smb_info_t *si = pinfo->private_data;
5982         int an_len;
5983         const char *an;
5984
5985         WORD_COUNT;
5986
5987         /* next smb command */
5988         cmd = tvb_get_guint8(tvb, offset);
5989         if(cmd!=0xff){
5990                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5991         } else {
5992                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5993         }
5994         offset += 1;
5995
5996         /* reserved byte */
5997         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5998         offset += 1;
5999
6000         /* andxoffset */
6001         andxoffset = tvb_get_letohs(tvb, offset);
6002         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6003         offset += 2;
6004
6005         /* flags */
6006         offset = dissect_setup_action(tvb, tree, offset);
6007
6008         if(wc==4){
6009                 /* security blob length */
6010                 sbloblen = tvb_get_letohs(tvb, offset);
6011                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6012                 offset += 2;
6013         }
6014
6015         BYTE_COUNT;
6016
6017         if(wc==4) {
6018                 proto_item *blob_item;
6019
6020                 /* security blob */
6021                 /* dont try to eat too much of we might get an exception on 
6022                  * short frames and then we will not see anything at all
6023                  * of the security blob.
6024                  */
6025                 if(sbloblen>tvb_length_remaining(tvb,offset)){
6026                         sbloblen=tvb_length_remaining(tvb,offset);
6027                 }
6028                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6029                                                 tvb, offset, sbloblen, TRUE);
6030
6031                 if(sbloblen){
6032                         tvbuff_t *blob_tvb;
6033                         proto_tree *blob_tree;
6034
6035                         blob_tree = proto_item_add_subtree(blob_item, 
6036                                                            ett_smb_secblob);
6037                         CHECK_BYTE_COUNT(sbloblen);
6038
6039                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6040                                                     sbloblen);
6041
6042                         if (si && si->ct && si->ct->raw_ntlmssp && 
6043                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6044                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6045                                          blob_tree);
6046
6047                         }
6048                         else {
6049                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6050                                          blob_tree);
6051
6052                         }
6053
6054                         COUNT_BYTES(sbloblen);
6055                 }
6056         }
6057
6058         /* OS */
6059         an = get_unicode_or_ascii_string(tvb, &offset,
6060                 si->unicode, &an_len, FALSE, FALSE, &bc);
6061         if (an == NULL)
6062                 goto endofcommand;
6063         proto_tree_add_string(tree, hf_smb_os, tvb,
6064                 offset, an_len, an);
6065         COUNT_BYTES(an_len);
6066
6067         /* LANMAN */
6068         an = get_unicode_or_ascii_string(tvb, &offset,
6069                 si->unicode, &an_len, FALSE, FALSE, &bc);
6070         if (an == NULL)
6071                 goto endofcommand;
6072         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6073                 offset, an_len, an);
6074         COUNT_BYTES(an_len);
6075
6076         if(wc==3) {
6077                 /* Primary domain */
6078                 an = get_unicode_or_ascii_string(tvb, &offset,
6079                         si->unicode, &an_len, FALSE, FALSE, &bc);
6080                 if (an == NULL)
6081                         goto endofcommand;
6082                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6083                         offset, an_len, an);
6084                 COUNT_BYTES(an_len);
6085         }
6086
6087         END_OF_SMB
6088
6089         /* call AndXCommand (if there are any) */
6090         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6091
6092         return offset;
6093 }
6094
6095
6096 static int
6097 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6098 {
6099         guint8  wc, cmd=0xff;
6100         guint16 andxoffset=0;
6101         guint16 bc;
6102
6103         WORD_COUNT;
6104
6105         /* next smb command */
6106         cmd = tvb_get_guint8(tvb, offset);
6107         if(cmd!=0xff){
6108                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6109         } else {
6110                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6111         }
6112         offset += 1;
6113
6114         /* reserved byte */
6115         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6116         offset += 1;
6117
6118         /* andxoffset */
6119         andxoffset = tvb_get_letohs(tvb, offset);
6120         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6121         offset += 2;
6122
6123         BYTE_COUNT;
6124
6125         END_OF_SMB
6126
6127         /* call AndXCommand (if there are any) */
6128         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6129
6130         return offset;
6131 }
6132
6133
6134 static const true_false_string tfs_connect_support_search = {
6135         "Exclusive search bits supported",
6136         "Exclusive search bits not supported"
6137 };
6138 static const true_false_string tfs_connect_support_in_dfs = {
6139         "Share is in Dfs",
6140         "Share isn't in Dfs"
6141 };
6142
6143 static int
6144 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6145 {
6146         guint16 mask;
6147         proto_item *item = NULL;
6148         proto_tree *tree = NULL;
6149
6150         mask = tvb_get_letohs(tvb, offset);
6151
6152         if(parent_tree){
6153                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6154                         "Optional Support: 0x%04x", mask);
6155                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6156         }
6157
6158         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6159                 tvb, offset, 2, mask);
6160         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6161                 tvb, offset, 2, mask);
6162
6163         offset += 2;
6164
6165         return offset;
6166 }
6167
6168 static const true_false_string tfs_disconnect_tid = {
6169         "DISCONNECT TID",
6170         "Do NOT disconnect TID"
6171 };
6172
6173 static int
6174 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6175 {
6176         guint16 mask;
6177         proto_item *item = NULL;
6178         proto_tree *tree = NULL;
6179
6180         mask = tvb_get_letohs(tvb, offset);
6181
6182         if(parent_tree){
6183                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6184                         "Flags: 0x%04x", mask);
6185                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6186         }
6187
6188         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6189                 tvb, offset, 2, mask);
6190
6191         offset += 2;
6192
6193         return offset;
6194 }
6195
6196 static int
6197 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6198 {
6199         guint8  wc, cmd=0xff;
6200         guint16 bc;
6201         guint16 andxoffset=0, pwlen=0;
6202         smb_info_t *si = pinfo->private_data;
6203         int an_len;
6204         const char *an;
6205
6206         WORD_COUNT;
6207
6208         /* next smb command */
6209         cmd = tvb_get_guint8(tvb, offset);
6210         if(cmd!=0xff){
6211                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6212         } else {
6213                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6214         }
6215         offset += 1;
6216
6217         /* reserved byte */
6218         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6219         offset += 1;
6220
6221         /* andxoffset */
6222         andxoffset = tvb_get_letohs(tvb, offset);
6223         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6224         offset += 2;
6225
6226         /* flags */
6227         offset = dissect_connect_flags(tvb, tree, offset);
6228
6229         /* password length*/
6230         pwlen = tvb_get_letohs(tvb, offset);
6231         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6232         offset += 2;
6233
6234         BYTE_COUNT;
6235
6236         /* password */
6237         CHECK_BYTE_COUNT(pwlen);
6238         proto_tree_add_item(tree, hf_smb_password,
6239                 tvb, offset, pwlen, TRUE);
6240         COUNT_BYTES(pwlen);
6241
6242         /* Path */
6243         an = get_unicode_or_ascii_string(tvb, &offset,
6244                 si->unicode, &an_len, FALSE, FALSE, &bc);
6245         if (an == NULL)
6246                 goto endofcommand;
6247         proto_tree_add_string(tree, hf_smb_path, tvb,
6248                 offset, an_len, an);
6249         COUNT_BYTES(an_len);
6250
6251         if (check_col(pinfo->cinfo, COL_INFO)) {
6252                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6253                     format_text(an, strlen(an)));
6254         }
6255
6256         /*
6257          * NOTE: the Service string is always ASCII, even if the
6258          * "strings are Unicode" bit is set in the flags2 field
6259          * of the SMB.
6260          */
6261
6262         /* Service */
6263         /* XXX - what if this runs past bc? */
6264         an_len = tvb_strsize(tvb, offset);
6265         CHECK_BYTE_COUNT(an_len);
6266         an = tvb_get_ptr(tvb, offset, an_len);
6267         proto_tree_add_string(tree, hf_smb_service, tvb,
6268                 offset, an_len, an);
6269         COUNT_BYTES(an_len);
6270
6271         END_OF_SMB
6272
6273         /* call AndXCommand (if there are any) */
6274         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6275
6276         return offset;
6277 }
6278
6279
6280 static int
6281 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6282 {
6283         guint8  wc, wleft, cmd=0xff;
6284         guint16 andxoffset=0;
6285         guint16 bc;
6286         int an_len;
6287         const char *an;
6288         smb_info_t *si = pinfo->private_data;
6289
6290         WORD_COUNT;
6291
6292         wleft = wc;     /* this is at least 1 */
6293
6294         /* next smb command */
6295         cmd = tvb_get_guint8(tvb, offset);
6296         if(cmd!=0xff){
6297                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6298         } else {
6299                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6300         }
6301         offset += 1;
6302
6303         /* reserved byte */
6304         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6305         offset += 1;
6306
6307         wleft--;
6308         if (wleft == 0)
6309                 goto bytecount;
6310
6311         /* andxoffset */
6312         andxoffset = tvb_get_letohs(tvb, offset);
6313         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6314         offset += 2;
6315         wleft--;
6316         if (wleft == 0)
6317                 goto bytecount;
6318
6319         /* flags */
6320         offset = dissect_connect_support_bits(tvb, tree, offset);
6321         wleft--;
6322
6323         /* XXX - I've seen captures where this is 7, but I have no
6324            idea how to dissect it.  I'm guessing the third word
6325            contains connect support bits, which looks plausible
6326            from the values I've seen. */
6327
6328         while (wleft != 0) {
6329                 proto_tree_add_text(tree, tvb, offset, 2,
6330                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6331                 offset += 2;
6332                 wleft--;
6333         }
6334
6335         BYTE_COUNT;
6336
6337         /*
6338          * NOTE: even though the SNIA CIFS spec doesn't say there's
6339          * a "Service" string if there's a word count of 2, the
6340          * document at
6341          *
6342          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6343          *
6344          * (it's in an ugly format - text intended to be sent to a
6345          * printer, with backspaces and overstrikes used for boldfacing
6346          * and underlining; UNIX "col -b" can be used to strip the
6347          * overstrikes out) says there's a "Service" string there, and
6348          * some network traffic has it.
6349          */
6350
6351         /*
6352          * NOTE: the Service string is always ASCII, even if the
6353          * "strings are Unicode" bit is set in the flags2 field
6354          * of the SMB.
6355          */
6356
6357         /* Service */
6358         /* XXX - what if this runs past bc? */
6359         an_len = tvb_strsize(tvb, offset);
6360         CHECK_BYTE_COUNT(an_len);
6361         an = tvb_get_ptr(tvb, offset, an_len);
6362         proto_tree_add_string(tree, hf_smb_service, tvb,
6363                 offset, an_len, an);
6364         COUNT_BYTES(an_len);
6365
6366         /* Now when we know the service type, store it so that we know it for later commands down
6367            this tree */
6368         if(!pinfo->fd->flags.visited){
6369                 /* Remove any previous entry for this TID */
6370                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6371                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6372                 }
6373                 if(strcmp(an,"IPC") == 0){
6374                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6375                 } else {
6376                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6377                 }
6378         }
6379
6380
6381         if(wc==3){
6382                 if (bc != 0) {
6383                         /*
6384                          * Sometimes this isn't present.
6385                          */
6386
6387                         /* Native FS */
6388                         an = get_unicode_or_ascii_string(tvb, &offset,
6389                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6390                                 &bc);
6391                         if (an == NULL)
6392                                 goto endofcommand;
6393                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6394                                 offset, an_len, an);
6395                         COUNT_BYTES(an_len);
6396                 }
6397         }
6398
6399         END_OF_SMB
6400
6401         /* call AndXCommand (if there are any) */
6402         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6403
6404         return offset;
6405 }
6406
6407
6408
6409 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6410    NT Transaction command  begins here
6411    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6412 #define NT_TRANS_CREATE         1
6413 #define NT_TRANS_IOCTL          2
6414 #define NT_TRANS_SSD            3
6415 #define NT_TRANS_NOTIFY         4
6416 #define NT_TRANS_RENAME         5
6417 #define NT_TRANS_QSD            6
6418 #define NT_TRANS_GET_USER_QUOTA 7
6419 #define NT_TRANS_SET_USER_QUOTA 8
6420 const value_string nt_cmd_vals[] = {
6421         {NT_TRANS_CREATE,               "NT CREATE"},
6422         {NT_TRANS_IOCTL,                "NT IOCTL"},
6423         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6424         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6425         {NT_TRANS_RENAME,               "NT RENAME"},
6426         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6427         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6428         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6429         {0, NULL}
6430 };
6431
6432 static const value_string nt_ioctl_isfsctl_vals[] = {
6433         {0,     "Device IOCTL"},
6434         {1,     "FS control : FSCTL"},
6435         {0, NULL}
6436 };
6437
6438 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6439 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6440         "Apply the command to share root handle (MUST BE Dfs)",
6441         "Apply to this share",
6442 };
6443
6444 static const value_string nt_notify_action_vals[] = {
6445         {1,     "ADDED (object was added"},
6446         {2,     "REMOVED (object was removed)"},
6447         {3,     "MODIFIED (object was modified)"},
6448         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6449         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6450         {6,     "ADDED_STREAM (a stream was added)"},
6451         {7,     "REMOVED_STREAM (a stream was removed)"},
6452         {8,     "MODIFIED_STREAM (a stream was modified)"},
6453         {0, NULL}
6454 };
6455
6456 static const value_string watch_tree_vals[] = {
6457         {0,     "Current directory only"},
6458         {1,     "Subdirectories also"},
6459         {0, NULL}
6460 };
6461
6462 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6463 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6464 #define NT_NOTIFY_STREAM_NAME   0x00000200
6465 #define NT_NOTIFY_SECURITY      0x00000100
6466 #define NT_NOTIFY_EA            0x00000080
6467 #define NT_NOTIFY_CREATION      0x00000040
6468 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6469 #define NT_NOTIFY_LAST_WRITE    0x00000010
6470 #define NT_NOTIFY_SIZE          0x00000008
6471 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6472 #define NT_NOTIFY_DIR_NAME      0x00000002
6473 #define NT_NOTIFY_FILE_NAME     0x00000001
6474 static const true_false_string tfs_nt_notify_stream_write = {
6475         "Notify on changes to STREAM WRITE",
6476         "Do NOT notify on changes to stream write",
6477 };
6478 static const true_false_string tfs_nt_notify_stream_size = {
6479         "Notify on changes to STREAM SIZE",
6480         "Do NOT notify on changes to stream size",
6481 };
6482 static const true_false_string tfs_nt_notify_stream_name = {
6483         "Notify on changes to STREAM NAME",
6484         "Do NOT notify on changes to stream name",
6485 };
6486 static const true_false_string tfs_nt_notify_security = {
6487         "Notify on changes to SECURITY",
6488         "Do NOT notify on changes to security",
6489 };
6490 static const true_false_string tfs_nt_notify_ea = {
6491         "Notify on changes to EA",
6492         "Do NOT notify on changes to EA",
6493 };
6494 static const true_false_string tfs_nt_notify_creation = {
6495         "Notify on changes to CREATION TIME",
6496         "Do NOT notify on changes to creation time",
6497 };
6498 static const true_false_string tfs_nt_notify_last_access = {
6499         "Notify on changes to LAST ACCESS TIME",
6500         "Do NOT notify on changes to last access time",
6501 };
6502 static const true_false_string tfs_nt_notify_last_write = {
6503         "Notify on changes to LAST WRITE TIME",
6504         "Do NOT notify on changes to last write time",
6505 };
6506 static const true_false_string tfs_nt_notify_size = {
6507         "Notify on changes to SIZE",
6508         "Do NOT notify on changes to size",
6509 };
6510 static const true_false_string tfs_nt_notify_attributes = {
6511         "Notify on changes to ATTRIBUTES",
6512         "Do NOT notify on changes to attributes",
6513 };
6514 static const true_false_string tfs_nt_notify_dir_name = {
6515         "Notify on changes to DIR NAME",
6516         "Do NOT notify on changes to dir name",
6517 };
6518 static const true_false_string tfs_nt_notify_file_name = {
6519         "Notify on changes to FILE NAME",
6520         "Do NOT notify on changes to file name",
6521 };
6522
6523 static const value_string create_disposition_vals[] = {
6524         {0,     "Supersede (supersede existing file (if it exists))"},
6525         {1,     "Open (if file exists open it, else fail)"},
6526         {2,     "Create (if file exists fail, else create it)"},
6527         {3,     "Open If (if file exists open it, else create it)"},
6528         {4,     "Overwrite (if file exists overwrite, else fail)"},
6529         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6530         {0, NULL}
6531 };
6532
6533 static const value_string impersonation_level_vals[] = {
6534         {0,     "Anonymous"},
6535         {1,     "Identification"},
6536         {2,     "Impersonation"},
6537         {3,     "Delegation"},
6538         {0, NULL}
6539 };
6540
6541 static const true_false_string tfs_nt_security_flags_context_tracking = {
6542         "Security tracking mode is DYNAMIC",
6543         "Security tracking mode is STATIC",
6544 };
6545
6546 static const true_false_string tfs_nt_security_flags_effective_only = {
6547         "ONLY ENABLED aspects of the client's security context are available",
6548         "ALL aspects of the client's security context are available",
6549 };
6550
6551 static const true_false_string tfs_nt_create_bits_oplock = {
6552         "Requesting OPLOCK",
6553         "Does NOT request oplock"
6554 };
6555
6556 static const true_false_string tfs_nt_create_bits_boplock = {
6557         "Requesting BATCH OPLOCK",
6558         "Does NOT request batch oplock"
6559 };
6560
6561 /*
6562  * XXX - must be a directory, and can be a file, or can be a directory,
6563  * and must be a file?
6564  */
6565 static const true_false_string tfs_nt_create_bits_dir = {
6566         "Target of open MUST be a DIRECTORY",
6567         "Target of open can be a file"
6568 };
6569
6570 static const true_false_string tfs_nt_create_bits_ext_resp = {
6571   "Extended responses required",
6572   "Extended responses NOT required"
6573 };
6574
6575 static const true_false_string tfs_nt_access_mask_generic_read = {
6576         "GENERIC READ is set",
6577         "Generic read is NOT set"
6578 };
6579 static const true_false_string tfs_nt_access_mask_generic_write = {
6580         "GENERIC WRITE is set",
6581         "Generic write is NOT set"
6582 };
6583 static const true_false_string tfs_nt_access_mask_generic_execute = {
6584         "GENERIC EXECUTE is set",
6585         "Generic execute is NOT set"
6586 };
6587 static const true_false_string tfs_nt_access_mask_generic_all = {
6588         "GENERIC ALL is set",
6589         "Generic all is NOT set"
6590 };
6591 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6592         "MAXIMUM ALLOWED is set",
6593         "Maximum allowed is NOT set"
6594 };
6595 static const true_false_string tfs_nt_access_mask_system_security = {
6596         "SYSTEM SECURITY is set",
6597         "System security is NOT set"
6598 };
6599 static const true_false_string tfs_nt_access_mask_synchronize = {
6600         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6601         "Can NOT wait on handle to synchronize on completion of I/O"
6602 };
6603 static const true_false_string tfs_nt_access_mask_write_owner = {
6604         "Can WRITE OWNER (take ownership)",
6605         "Can NOT write owner (take ownership)"
6606 };
6607 static const true_false_string tfs_nt_access_mask_write_dac = {
6608         "OWNER may WRITE the DAC",
6609         "Owner may NOT write to the DAC"
6610 };
6611 static const true_false_string tfs_nt_access_mask_read_control = {
6612         "READ ACCESS to owner, group and ACL of the SID",
6613         "Read access is NOT granted to owner, group and ACL of the SID"
6614 };
6615 static const true_false_string tfs_nt_access_mask_delete = {
6616         "DELETE access",
6617         "NO delete access"
6618 };
6619 static const true_false_string tfs_nt_access_mask_write_attributes = {
6620         "WRITE ATTRIBUTES access",
6621         "NO write attributes access"
6622 };
6623 static const true_false_string tfs_nt_access_mask_read_attributes = {
6624         "READ ATTRIBUTES access",
6625         "NO read attributes access"
6626 };
6627 static const true_false_string tfs_nt_access_mask_delete_child = {
6628         "DELETE CHILD access",
6629         "NO delete child access"
6630 };
6631 static const true_false_string tfs_nt_access_mask_execute = {
6632         "EXECUTE access",
6633         "NO execute access"
6634 };
6635 static const true_false_string tfs_nt_access_mask_write_ea = {
6636         "WRITE EXTENDED ATTRIBUTES access",
6637         "NO write extended attributes access"
6638 };
6639 static const true_false_string tfs_nt_access_mask_read_ea = {
6640         "READ EXTENDED ATTRIBUTES access",
6641         "NO read extended attributes access"
6642 };
6643 static const true_false_string tfs_nt_access_mask_append = {
6644         "APPEND access",
6645         "NO append access"
6646 };
6647 static const true_false_string tfs_nt_access_mask_write = {
6648         "WRITE access",
6649         "NO write access"
6650 };
6651 static const true_false_string tfs_nt_access_mask_read = {
6652         "READ access",
6653         "NO read access"
6654 };
6655
6656 static const true_false_string tfs_nt_share_access_delete = {
6657         "Object can be shared for DELETE",
6658         "Object can NOT be shared for delete"
6659 };
6660 static const true_false_string tfs_nt_share_access_write = {
6661         "Object can be shared for WRITE",
6662         "Object can NOT be shared for write"
6663 };
6664 static const true_false_string tfs_nt_share_access_read = {
6665         "Object can be shared for READ",
6666         "Object can NOT be shared for read"
6667 };
6668
6669 static const value_string oplock_level_vals[] = {
6670         {0,     "No oplock granted"},
6671         {1,     "Exclusive oplock granted"},
6672         {2,     "Batch oplock granted"},
6673         {3,     "Level II oplock granted"},
6674         {0, NULL}
6675 };
6676
6677 static const value_string device_type_vals[] = {
6678         {0x00000001,    "Beep"},
6679         {0x00000002,    "CDROM"},
6680         {0x00000003,    "CDROM Filesystem"},
6681         {0x00000004,    "Controller"},
6682         {0x00000005,    "Datalink"},
6683         {0x00000006,    "Dfs"},
6684         {0x00000007,    "Disk"},
6685         {0x00000008,    "Disk Filesystem"},
6686         {0x00000009,    "Filesystem"},
6687         {0x0000000a,    "Inport Port"},
6688         {0x0000000b,    "Keyboard"},
6689         {0x0000000c,    "Mailslot"},
6690         {0x0000000d,    "MIDI-In"},
6691         {0x0000000e,    "MIDI-Out"},
6692         {0x0000000f,    "Mouse"},
6693         {0x00000010,    "Multi UNC Provider"},
6694         {0x00000011,    "Named Pipe"},
6695         {0x00000012,    "Network"},
6696         {0x00000013,    "Network Browser"},
6697         {0x00000014,    "Network Filesystem"},
6698         {0x00000015,    "NULL"},
6699         {0x00000016,    "Parallel Port"},
6700         {0x00000017,    "Physical card"},
6701         {0x00000018,    "Printer"},
6702         {0x00000019,    "Scanner"},
6703         {0x0000001a,    "Serial Mouse port"},
6704         {0x0000001b,    "Serial port"},
6705         {0x0000001c,    "Screen"},
6706         {0x0000001d,    "Sound"},
6707         {0x0000001e,    "Streams"},
6708         {0x0000001f,    "Tape"},
6709         {0x00000020,    "Tape Filesystem"},
6710         {0x00000021,    "Transport"},
6711         {0x00000022,    "Unknown"},
6712         {0x00000023,    "Video"},
6713         {0x00000024,    "Virtual Disk"},
6714         {0x00000025,    "WAVE-In"},
6715         {0x00000026,    "WAVE-Out"},
6716         {0x00000027,    "8042 Port"},
6717         {0x00000028,    "Network Redirector"},
6718         {0x00000029,    "Battery"},
6719         {0x0000002a,    "Bus Extender"},
6720         {0x0000002b,    "Modem"},
6721         {0x0000002c,    "VDM"},
6722         {0,     NULL}
6723 };
6724
6725 static const value_string is_directory_vals[] = {
6726         {0,     "This is NOT a directory"},
6727         {1,     "This is a DIRECTORY"},
6728         {0, NULL}
6729 };
6730
6731 typedef struct _nt_trans_data {
6732         int subcmd;
6733         guint32 sd_len;
6734         guint32 ea_len;
6735 } nt_trans_data;
6736
6737
6738
6739 static int
6740 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6741 {
6742         guint8 mask;
6743         proto_item *item = NULL;
6744         proto_tree *tree = NULL;
6745
6746         mask = tvb_get_guint8(tvb, offset);
6747
6748         if(parent_tree){
6749                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6750                         "Security Flags: 0x%02x", mask);
6751                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6752         }
6753
6754         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6755                 tvb, offset, 1, mask);
6756         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6757                 tvb, offset, 1, mask);
6758
6759         offset += 1;
6760
6761         return offset;
6762 }
6763
6764 static int
6765 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6766 {
6767         guint32 mask;
6768         proto_item *item = NULL;
6769         proto_tree *tree = NULL;
6770
6771         mask = tvb_get_letohl(tvb, offset);
6772
6773         if(parent_tree){
6774                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6775                         "Share Access: 0x%08x", mask);
6776                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6777         }
6778
6779         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6780                 tvb, offset, 4, mask);
6781         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6782                 tvb, offset, 4, mask);
6783         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6784                 tvb, offset, 4, mask);
6785
6786         offset += 4;
6787
6788         return offset;
6789 }
6790
6791 /* FIXME: need to call dissect_nt_access_mask() instead */
6792
6793 static int
6794 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6795 {
6796         guint32 mask;
6797         proto_item *item = NULL;
6798         proto_tree *tree = NULL;
6799
6800         mask = tvb_get_letohl(tvb, offset);
6801
6802         if(parent_tree){
6803                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6804                         "Access Mask: 0x%08x", mask);
6805                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6806         }
6807
6808         /*
6809          * Some of these bits come from
6810          *
6811          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6812          *
6813          * and others come from the section on ZwOpenFile in "Windows(R)
6814          * NT(R)/2000 Native API Reference".
6815          */
6816         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6817                 tvb, offset, 4, mask);
6818         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6819                 tvb, offset, 4, mask);
6820         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6821                 tvb, offset, 4, mask);
6822         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6823                 tvb, offset, 4, mask);
6824         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6825                 tvb, offset, 4, mask);
6826         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6827                 tvb, offset, 4, mask);
6828         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6829                 tvb, offset, 4, mask);
6830         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6831                 tvb, offset, 4, mask);
6832         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6833                 tvb, offset, 4, mask);
6834         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6835                 tvb, offset, 4, mask);
6836         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6837                 tvb, offset, 4, mask);
6838         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6839                 tvb, offset, 4, mask);
6840         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6841                 tvb, offset, 4, mask);
6842         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6843                 tvb, offset, 4, mask);
6844         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6855                 tvb, offset, 4, mask);
6856
6857         offset += 4;
6858
6859         return offset;
6860 }
6861
6862 static int
6863 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6864 {
6865         guint32 mask;
6866         proto_item *item = NULL;
6867         proto_tree *tree = NULL;
6868
6869         mask = tvb_get_letohl(tvb, offset);
6870
6871         if(parent_tree){
6872                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6873                         "Create Flags: 0x%08x", mask);
6874                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6875         }
6876
6877         /*
6878          * XXX - it's 0x00000016 in at least one capture, but
6879          * Network Monitor doesn't say what the 0x00000010 bit is.
6880          * Does the Win32 API documentation, or NT Native API book,
6881          * suggest anything?
6882          *
6883          * That is the extended response desired bit ... RJS, from Samba
6884          * Well, maybe. Samba thinks it is, and uses it to encode
6885          * OpLock granted as the high order bit of the Action field
6886          * in the response. However, Windows does not do that. Or at least
6887          * Win2K doesn't.
6888          */
6889         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6890                                tvb, offset, 4, mask);
6891         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6892                 tvb, offset, 4, mask);
6893         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6894                 tvb, offset, 4, mask);
6895         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6896                 tvb, offset, 4, mask);
6897
6898         offset += 4;
6899
6900         return offset;
6901 }
6902
6903 /*
6904  * XXX - there are some more flags in the description of "ZwOpenFile()"
6905  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6906  * the wire as well?  (The spec at
6907  *
6908  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6909  *
6910  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6911  * via the SMB protocol.  The NT redirector should convert this option
6912  * to FILE_WRITE_THROUGH."
6913  *
6914  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6915  * values one would infer from their position in the list of flags for
6916  * "ZwOpenFile()".  Most of the others probably have those values
6917  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6918  * which might go over the wire (for the benefit of backup/restore software).
6919  */
6920 static const true_false_string tfs_nt_create_options_directory = {
6921         "File being created/opened must be a directory",
6922         "File being created/opened must not be a directory"
6923 };
6924 static const true_false_string tfs_nt_create_options_write_through = {
6925         "Writes should flush buffered data before completing",
6926         "Writes need not flush buffered data before completing"
6927 };
6928 static const true_false_string tfs_nt_create_options_sequential_only = {
6929         "The file will only be accessed sequentially",
6930         "The file might not only be accessed sequentially"
6931 };
6932 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6933         "All operations SYNCHRONOUS, waits subject to termination from alert",
6934         "Operations NOT necessarily synchronous"
6935 };
6936 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6937         "All operations SYNCHRONOUS, waits not subject to alert",
6938         "Operations NOT necessarily synchronous"
6939 };
6940 static const true_false_string tfs_nt_create_options_non_directory = {
6941         "File being created/opened must not be a directory",
6942         "File being created/opened must be a directory"
6943 };
6944 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6945         "The client does not understand extended attributes",
6946         "The client understands extended attributes"
6947 };
6948 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6949         "The client understands only 8.3 file names",
6950         "The client understands long file names"
6951 };
6952 static const true_false_string tfs_nt_create_options_random_access = {
6953         "The file will be accessed randomly",
6954         "The file will not be accessed randomly"
6955 };
6956 static const true_false_string tfs_nt_create_options_delete_on_close = {
6957         "The file should be deleted when it is closed",
6958         "The file should not be deleted when it is closed"
6959 };
6960
6961 static int
6962 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6963 {
6964         guint32 mask;
6965         proto_item *item = NULL;
6966         proto_tree *tree = NULL;
6967
6968         mask = tvb_get_letohl(tvb, offset);
6969
6970         if(parent_tree){
6971                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6972                         "Create Options: 0x%08x", mask);
6973                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6974         }
6975
6976         /*
6977          * From
6978          *
6979          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6980          */
6981         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6982                 tvb, offset, 4, mask);
6983         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6984                 tvb, offset, 4, mask);
6985         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6986                 tvb, offset, 4, mask);
6987         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6988                 tvb, offset, 4, mask);
6989         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6990                 tvb, offset, 4, mask);
6991         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6992                 tvb, offset, 4, mask);
6993         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6994                 tvb, offset, 4, mask);
6995         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6996                 tvb, offset, 4, mask);
6997         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6998                 tvb, offset, 4, mask);
6999         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
7000                 tvb, offset, 4, mask);
7001
7002         offset += 4;
7003
7004         return offset;
7005 }
7006
7007 static int
7008 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7009 {
7010         guint32 mask;
7011         proto_item *item = NULL;
7012         proto_tree *tree = NULL;
7013
7014         mask = tvb_get_letohl(tvb, offset);
7015
7016         if(parent_tree){
7017                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7018                         "Completion Filter: 0x%08x", mask);
7019                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7020         }
7021
7022         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7023                 tvb, offset, 4, mask);
7024         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7025                 tvb, offset, 4, mask);
7026         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7027                 tvb, offset, 4, mask);
7028         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7029                 tvb, offset, 4, mask);
7030         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7031                 tvb, offset, 4, mask);
7032         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7033                 tvb, offset, 4, mask);
7034         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7035                 tvb, offset, 4, mask);
7036         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7037                 tvb, offset, 4, mask);
7038         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7039                 tvb, offset, 4, mask);
7040         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7041                 tvb, offset, 4, mask);
7042         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7043                 tvb, offset, 4, mask);
7044         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7045                 tvb, offset, 4, mask);
7046
7047         offset += 4;
7048         return offset;
7049 }
7050
7051 static int
7052 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7053 {
7054         guint8 mask;
7055         proto_item *item = NULL;
7056         proto_tree *tree = NULL;
7057
7058         mask = tvb_get_guint8(tvb, offset);
7059
7060         if(parent_tree){
7061                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7062                         "Completion Filter: 0x%02x", mask);
7063                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7064         }
7065
7066         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7067                 tvb, offset, 1, mask);
7068
7069         offset += 1;
7070         return offset;
7071 }
7072
7073 /*
7074  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7075  * Native API Reference".
7076  */
7077 static const true_false_string tfs_nt_qsd_owner = {
7078         "Requesting OWNER security information",
7079         "NOT requesting owner security information",
7080 };
7081
7082 static const true_false_string tfs_nt_qsd_group = {
7083         "Requesting GROUP security information",
7084         "NOT requesting group security information",
7085 };
7086
7087 static const true_false_string tfs_nt_qsd_dacl = {
7088         "Requesting DACL security information",
7089         "NOT requesting DACL security information",
7090 };
7091
7092 static const true_false_string tfs_nt_qsd_sacl = {
7093         "Requesting SACL security information",
7094         "NOT requesting SACL security information",
7095 };
7096
7097 #define NT_QSD_OWNER    0x00000001
7098 #define NT_QSD_GROUP    0x00000002
7099 #define NT_QSD_DACL     0x00000004
7100 #define NT_QSD_SACL     0x00000008
7101
7102 static int
7103 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7104 {
7105         guint32 mask;
7106         proto_item *item = NULL;
7107         proto_tree *tree = NULL;
7108
7109         mask = tvb_get_letohl(tvb, offset);
7110
7111         if(parent_tree){
7112                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7113                         "Security Information: 0x%08x", mask);
7114                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7115         }
7116
7117         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7118                 tvb, offset, 4, mask);
7119         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7120                 tvb, offset, 4, mask);
7121         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7122                 tvb, offset, 4, mask);
7123         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7124                 tvb, offset, 4, mask);
7125
7126         offset += 4;
7127
7128         return offset;
7129 }
7130
7131 static int
7132 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7133 {
7134         int old_offset, old_sid_offset;
7135         guint32 qsize;
7136
7137         do {
7138                 old_offset=offset;
7139
7140                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7141                 qsize=tvb_get_letohl(tvb, offset);
7142                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7143                 COUNT_BYTES_TRANS_SUBR(4);
7144
7145                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7146                 /* length of SID */
7147                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7148                 COUNT_BYTES_TRANS_SUBR(4);
7149
7150                 /* 16 unknown bytes */
7151                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7152                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7153                             offset, 8, TRUE);
7154                 COUNT_BYTES_TRANS_SUBR(8);
7155
7156                 /* number of bytes for used quota */
7157                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7158                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7159                 COUNT_BYTES_TRANS_SUBR(8);
7160
7161                 /* number of bytes for quota warning */
7162                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7163                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7164                 COUNT_BYTES_TRANS_SUBR(8);
7165
7166                 /* number of bytes for quota limit */
7167                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7168                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7169                 COUNT_BYTES_TRANS_SUBR(8);
7170
7171                 /* SID of the user */
7172                 old_sid_offset=offset;
7173                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7174                 *bcp -= (offset-old_sid_offset);
7175
7176                 if(qsize){
7177                         offset = old_offset+qsize;
7178                 }
7179         }while(qsize);
7180
7181
7182         return offset;
7183 }
7184
7185
7186 static int
7187 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7188 {
7189         proto_item *item = NULL;
7190         proto_tree *tree = NULL;
7191         smb_info_t *si;
7192         int old_offset = offset;
7193         guint16 bcp=bc; /* XXX fixme */
7194
7195         si = (smb_info_t *)pinfo->private_data;
7196
7197         if(parent_tree){
7198                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7199                                 "%s Data",
7200                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7201                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7202         }
7203
7204         switch(ntd->subcmd){
7205         case NT_TRANS_CREATE:
7206                 /* security descriptor */
7207                 if(ntd->sd_len){
7208                         offset = dissect_nt_sec_desc(
7209                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
7210                                 NULL);
7211                 }
7212
7213                 /* extended attributes */
7214                 if(ntd->ea_len){
7215                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7216                         offset += ntd->ea_len;
7217                 }
7218
7219                 break;
7220         case NT_TRANS_IOCTL:
7221                 /* ioctl data */
7222                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7223                 offset += bc;
7224
7225                 break;
7226         case NT_TRANS_SSD:
7227                 offset = dissect_nt_sec_desc(
7228                         tvb, offset, pinfo, tree, NULL, bc, NULL);
7229                 break;
7230         case NT_TRANS_NOTIFY:
7231                 break;
7232         case NT_TRANS_RENAME:
7233                 /* XXX not documented */
7234                 break;
7235         case NT_TRANS_QSD:
7236                 break;
7237         case NT_TRANS_GET_USER_QUOTA:
7238                 /* unknown 4 bytes */
7239                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7240                             offset, 4, TRUE);
7241                 offset += 4;
7242
7243                 /* length of SID */
7244                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7245                 offset +=4;
7246
7247                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7248                 break;
7249         case NT_TRANS_SET_USER_QUOTA:
7250                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7251                 break;
7252         }
7253
7254         /* ooops there were data we didnt know how to process */
7255         if((offset-old_offset) < bc){
7256                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7257                     bc - (offset-old_offset), TRUE);
7258                 offset += bc - (offset-old_offset);
7259         }
7260
7261         return offset;
7262 }
7263
7264 static int
7265 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)
7266 {
7267         proto_item *item = NULL;
7268         proto_tree *tree = NULL;
7269         smb_info_t *si;
7270         guint32 fn_len;
7271         const char *fn;
7272
7273         si = (smb_info_t *)pinfo->private_data;
7274
7275         if(parent_tree){
7276                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7277                                 "%s Parameters",
7278                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7279                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7280         }
7281
7282         switch(ntd->subcmd){
7283         case NT_TRANS_CREATE:
7284                 /* Create flags */
7285                 offset = dissect_nt_create_bits(tvb, tree, offset);
7286                 bc -= 4;
7287
7288                 /* root directory fid */
7289                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7290                 COUNT_BYTES(4);
7291
7292                 /* nt access mask */
7293                 offset = dissect_smb_access_mask(tvb, tree, offset);
7294                 bc -= 4;
7295
7296                 /* allocation size */
7297                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7298                 COUNT_BYTES(8);
7299
7300                 /* Extended File Attributes */
7301                 offset = dissect_file_ext_attr(tvb, tree, offset);
7302                 bc -= 4;
7303
7304                 /* share access */
7305                 offset = dissect_nt_share_access(tvb, tree, offset);
7306                 bc -= 4;
7307
7308                 /* create disposition */
7309                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7310                 COUNT_BYTES(4);
7311
7312                 /* create options */
7313                 offset = dissect_nt_create_options(tvb, tree, offset);
7314                 bc -= 4;
7315
7316                 /* sd length */
7317                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7318                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7319                 COUNT_BYTES(4);
7320
7321                 /* ea length */
7322                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7323                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
7324                 COUNT_BYTES(4);
7325
7326                 /* file name len */
7327                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7328                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7329                 COUNT_BYTES(4);
7330
7331                 /* impersonation level */
7332                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7333                 COUNT_BYTES(4);
7334
7335                 /* security flags */
7336                 offset = dissect_nt_security_flags(tvb, tree, offset);
7337                 bc -= 1;
7338
7339                 /* file name */
7340                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
7341                 if (fn != NULL) {
7342                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7343                                 fn);
7344                         COUNT_BYTES(fn_len);
7345                 }
7346
7347                 break;
7348         case NT_TRANS_IOCTL:
7349                 break;
7350         case NT_TRANS_SSD: {
7351                 guint16 fid;
7352
7353                 /* fid */
7354                 fid = tvb_get_letohs(tvb, offset);
7355                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7356                 offset += 2;
7357
7358                 /* 2 reserved bytes */
7359                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7360                 offset += 2;
7361
7362                 /* security information */
7363                 offset = dissect_security_information_mask(tvb, tree, offset);
7364                 break;
7365         }
7366         case NT_TRANS_NOTIFY:
7367                 break;
7368         case NT_TRANS_RENAME:
7369                 /* XXX not documented */
7370                 break;
7371         case NT_TRANS_QSD: {
7372                 guint16 fid;
7373
7374                 /* fid */
7375                 fid = tvb_get_letohs(tvb, offset);
7376                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7377                 offset += 2;
7378
7379                 /* 2 reserved bytes */
7380                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7381                 offset += 2;
7382
7383                 /* security information */
7384                 offset = dissect_security_information_mask(tvb, tree, offset);
7385                 break;
7386         }
7387         case NT_TRANS_GET_USER_QUOTA:
7388                 /* not decoded yet */
7389                 break;
7390         case NT_TRANS_SET_USER_QUOTA:
7391                 /* not decoded yet */
7392                 break;
7393         }
7394
7395         return offset;
7396 }
7397
7398 static int
7399 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7400 {
7401         proto_item *item = NULL;
7402         proto_tree *tree = NULL;
7403         smb_info_t *si;
7404         int old_offset = offset;
7405
7406         si = (smb_info_t *)pinfo->private_data;
7407
7408         if(parent_tree){
7409                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7410                                 "%s Setup",
7411                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7412                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7413         }
7414
7415         switch(ntd->subcmd){
7416         case NT_TRANS_CREATE:
7417                 break;
7418         case NT_TRANS_IOCTL: {
7419                 guint16 fid;
7420
7421                 /* function code */
7422                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7423                 offset += 4;
7424
7425                 /* fid */
7426                 fid = tvb_get_letohs(tvb, offset);
7427                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7428                 offset += 2;
7429
7430                 /* isfsctl */
7431                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7432                 offset += 1;
7433
7434                 /* isflags */
7435                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
7436
7437                 break;
7438         }
7439         case NT_TRANS_SSD:
7440                 break;
7441         case NT_TRANS_NOTIFY: {
7442                 guint16 fid;
7443
7444                 /* completion filter */
7445                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
7446
7447                 /* fid */
7448                 fid = tvb_get_letohs(tvb, offset);
7449                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7450                 offset += 2;
7451
7452                 /* watch tree */
7453                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7454                 offset += 1;
7455
7456                 /* reserved byte */
7457                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7458                 offset += 1;
7459
7460                 break;
7461         }
7462         case NT_TRANS_RENAME:
7463                 /* XXX not documented */
7464                 break;
7465         case NT_TRANS_QSD:
7466                 break;
7467         case NT_TRANS_GET_USER_QUOTA:
7468                 /* not decoded yet */
7469                 break;
7470         case NT_TRANS_SET_USER_QUOTA:
7471                 /* not decoded yet */
7472                 break;
7473         }
7474
7475         return old_offset+len;
7476 }
7477
7478
7479 static int
7480 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
7481 {
7482         guint8 wc, sc;
7483         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7484         smb_info_t *si;
7485         smb_saved_info_t *sip;
7486         int subcmd;
7487         nt_trans_data ntd;
7488         guint16 bc;
7489         int padcnt;
7490         smb_nt_transact_info_t *nti;
7491
7492         si = (smb_info_t *)pinfo->private_data;
7493         sip = si->sip;
7494
7495         WORD_COUNT;
7496
7497         if(wc>=19){
7498                 /* primary request */
7499                 /* max setup count */
7500                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7501                 offset += 1;
7502
7503                 /* 2 reserved bytes */
7504                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7505                 offset += 2;
7506         } else {
7507                 /* secondary request */
7508                 /* 3 reserved bytes */
7509                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7510                 offset += 3;
7511         }
7512
7513
7514         /* total param count */
7515         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7516         offset += 4;
7517
7518         /* total data count */
7519         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7520         offset += 4;
7521
7522         if(wc>=19){
7523                 /* primary request */
7524                 /* max param count */
7525                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7526                 offset += 4;
7527
7528                 /* max data count */
7529                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7530                 offset += 4;
7531         }
7532
7533         /* param count */
7534         pc = tvb_get_letohl(tvb, offset);
7535         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7536         offset += 4;
7537
7538         /* param offset */
7539         po = tvb_get_letohl(tvb, offset);
7540         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7541         offset += 4;
7542
7543         /* param displacement */
7544         if(wc>=19){
7545                 /* primary request*/
7546                 pd = 0;
7547         } else {
7548                 /* secondary request */
7549                 pd = tvb_get_letohl(tvb, offset);
7550                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7551                 offset += 4;
7552         }
7553
7554         /* data count */
7555         dc = tvb_get_letohl(tvb, offset);
7556         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7557         offset += 4;
7558
7559         /* data offset */
7560         od = tvb_get_letohl(tvb, offset);
7561         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7562         offset += 4;
7563
7564         /* data displacement */
7565         if(wc>=19){
7566                 /* primary request */
7567                 dd = 0;
7568         } else {
7569                 /* secondary request */
7570                 dd = tvb_get_letohl(tvb, offset);
7571                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7572                 offset += 4;
7573         }
7574
7575         /* setup count */
7576         if(wc>=19){
7577                 /* primary request */
7578                 sc = tvb_get_guint8(tvb, offset);
7579                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7580                 offset += 1;
7581         } else {
7582                 /* secondary request */
7583                 sc = 0;
7584         }
7585
7586         /* function */
7587         if(wc>=19){
7588                 /* primary request */
7589                 subcmd = tvb_get_letohs(tvb, offset);
7590                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7591                 if(check_col(pinfo->cinfo, COL_INFO)){
7592                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7593                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7594                 }
7595                 ntd.subcmd = subcmd;
7596                 if (!si->unidir) {
7597                         if(!pinfo->fd->flags.visited){
7598                                 /*
7599                                  * Allocate a new smb_nt_transact_info_t
7600                                  * structure.
7601                                  */
7602                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7603                                 nti->subcmd = subcmd;
7604                                 sip->extra_info = nti;
7605                         }
7606                 }
7607         } else {
7608                 /* secondary request */
7609                 if(check_col(pinfo->cinfo, COL_INFO)){
7610                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7611                 }
7612         }
7613         offset += 2;
7614
7615         /* this is a padding byte */
7616         if(offset%1){
7617                 /* pad byte */
7618                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7619                 offset += 1;
7620         }
7621
7622         /* if there were any setup bytes, decode them */
7623         if(sc){
7624                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7625                 offset += sc*2;
7626         }
7627
7628         BYTE_COUNT;
7629
7630         /* parameters */
7631         if(po>(guint32)offset){
7632                 /* We have some initial padding bytes.
7633                 */
7634                 padcnt = po-offset;
7635                 if (padcnt > bc)
7636                         padcnt = bc;
7637                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7638                 COUNT_BYTES(padcnt);
7639         }
7640         if(pc){
7641                 CHECK_BYTE_COUNT(pc);
7642                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7643                 COUNT_BYTES(pc);
7644         }
7645
7646         /* data */
7647         if(od>(guint32)offset){
7648                 /* We have some initial padding bytes.
7649                 */
7650                 padcnt = od-offset;
7651                 if (padcnt > bc)
7652                         padcnt = bc;
7653                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7654                 COUNT_BYTES(padcnt);
7655         }
7656         if(dc){
7657                 CHECK_BYTE_COUNT(dc);
7658                 dissect_nt_trans_data_request(
7659                         tvb, pinfo, offset, tree, dc, &ntd);
7660                 COUNT_BYTES(dc);
7661         }
7662
7663         END_OF_SMB
7664
7665         return offset;
7666 }
7667
7668
7669
7670 static int
7671 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
7672                                int offset, proto_tree *parent_tree, int len,
7673                                nt_trans_data *ntd _U_)
7674 {
7675         proto_item *item = NULL;
7676         proto_tree *tree = NULL;
7677         smb_info_t *si;
7678         smb_nt_transact_info_t *nti;
7679         guint16 bcp;
7680
7681         si = (smb_info_t *)pinfo->private_data;
7682         if (si->sip != NULL)
7683                 nti = si->sip->extra_info;
7684         else
7685                 nti = NULL;
7686
7687         if(parent_tree){
7688                 if(nti != NULL){
7689                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7690                                 "%s Data",
7691                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7692                 } else {
7693                         /*
7694                          * We never saw the request to which this is a
7695                          * response.
7696                          */
7697                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7698                                 "Unknown NT Transaction Data (matching request not seen)");
7699                 }
7700                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7701         }
7702
7703         if (nti == NULL) {
7704                 offset += len;
7705                 return offset;
7706         }
7707         switch(nti->subcmd){
7708         case NT_TRANS_CREATE:
7709                 break;
7710         case NT_TRANS_IOCTL:
7711                 /* ioctl data */
7712                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7713                 offset += len;
7714
7715                 break;
7716         case NT_TRANS_SSD:
7717                 break;
7718         case NT_TRANS_NOTIFY:
7719                 break;
7720         case NT_TRANS_RENAME:
7721                 /* XXX not documented */
7722                 break;
7723         case NT_TRANS_QSD: {
7724                 /*
7725                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7726                  * which may be documented in the Win32 documentation
7727                  * somewhere.
7728                  */
7729                 offset = dissect_nt_sec_desc(
7730                         tvb, offset, pinfo, tree, NULL, len, NULL);
7731                 break;
7732         }
7733         case NT_TRANS_GET_USER_QUOTA:
7734                 bcp=len;
7735                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7736                 break;
7737         case NT_TRANS_SET_USER_QUOTA:
7738                 /* not decoded yet */
7739                 break;
7740         }
7741
7742         return offset;
7743 }
7744
7745 static int
7746 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
7747                                 int offset, proto_tree *parent_tree,
7748                                 int len, nt_trans_data *ntd _U_, guint16 bc)
7749 {
7750         proto_item *item = NULL;
7751         proto_tree *tree = NULL;
7752         guint32 fn_len;
7753         const char *fn;
7754         smb_info_t *si;
7755         smb_nt_transact_info_t *nti;
7756         guint16 fid;
7757         int old_offset;
7758         guint32 neo;
7759         int padcnt;
7760
7761         si = (smb_info_t *)pinfo->private_data;
7762         if (si->sip != NULL)
7763                 nti = si->sip->extra_info;
7764         else
7765                 nti = NULL;
7766
7767         if(parent_tree){
7768                 if(nti != NULL){
7769                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7770                                 "%s Parameters",
7771                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7772                 } else {
7773                         /*
7774                          * We never saw the request to which this is a
7775                          * response.
7776                          */
7777                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7778                                 "Unknown NT Transaction Parameters (matching request not seen)");
7779                 }
7780                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7781         }
7782
7783         if (nti == NULL) {
7784                 offset += len;
7785                 return offset;
7786         }
7787         switch(nti->subcmd){
7788         case NT_TRANS_CREATE:
7789                 /* oplock level */
7790                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7791                 offset += 1;
7792
7793                 /* reserved byte */
7794                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7795                 offset += 1;
7796
7797                 /* fid */
7798                 fid = tvb_get_letohs(tvb, offset);
7799                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7800                 offset += 2;
7801
7802                 /* create action */
7803                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7804                 offset += 4;
7805
7806                 /* ea error offset */
7807                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7808                 offset += 4;
7809
7810                 /* create time */
7811                 offset = dissect_nt_64bit_time(tvb, tree, offset,
7812                         hf_smb_create_time);
7813
7814                 /* access time */
7815                 offset = dissect_nt_64bit_time(tvb, tree, offset,
7816                         hf_smb_access_time);
7817
7818                 /* last write time */
7819                 offset = dissect_nt_64bit_time(tvb, tree, offset,
7820                         hf_smb_last_write_time);
7821
7822                 /* last change time */
7823                 offset = dissect_nt_64bit_time(tvb, tree, offset,
7824                         hf_smb_change_time);
7825
7826                 /* Extended File Attributes */
7827                 offset = dissect_file_ext_attr(tvb, tree, offset);
7828
7829                 /* allocation size */
7830                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7831                 offset += 8;
7832
7833                 /* end of file */
7834                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7835                 offset += 8;
7836
7837                 /* File Type */
7838                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7839                 offset += 2;
7840
7841                 /* device state */
7842                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
7843
7844                 /* is directory */
7845                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7846                 offset += 1;
7847                 break;
7848         case NT_TRANS_IOCTL:
7849                 break;
7850         case NT_TRANS_SSD:
7851                 break;
7852         case NT_TRANS_NOTIFY:
7853                 while(len){
7854                         old_offset = offset;
7855
7856                         /* next entry offset */
7857                         neo = tvb_get_letohl(tvb, offset);
7858                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
7859                         COUNT_BYTES(4);
7860                         len -= 4;
7861                         /* broken implementations */
7862                         if(len<0)break;
7863
7864                         /* action */
7865                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
7866                         COUNT_BYTES(4);
7867                         len -= 4;
7868                         /* broken implementations */
7869                         if(len<0)break;
7870
7871                         /* file name len */
7872                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
7873                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7874                         COUNT_BYTES(4);
7875                         len -= 4;
7876                         /* broken implementations */
7877                         if(len<0)break;
7878
7879                         /* file name */
7880                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
7881                         if (fn == NULL)
7882                                 break;
7883                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7884                                 fn);
7885                         COUNT_BYTES(fn_len);
7886                         len -= fn_len;
7887                         /* broken implementations */
7888                         if(len<0)break;
7889
7890                         if (neo == 0)
7891                                 break;  /* no more structures */
7892
7893                         /* skip to next structure */
7894                         padcnt = (old_offset + neo) - offset;
7895                         if (padcnt < 0) {
7896                                 /*
7897                                  * XXX - this is bogus; flag it?
7898                                  */
7899                                 padcnt = 0;
7900                         }
7901                         if (padcnt != 0) {
7902                                 COUNT_BYTES(padcnt);
7903                                 len -= padcnt;
7904                                 /* broken implementations */
7905                                 if(len<0)break;
7906                         }
7907                 }
7908                 break;
7909         case NT_TRANS_RENAME:
7910                 /* XXX not documented */
7911                 break;
7912         case NT_TRANS_QSD:
7913                 /*
7914                  * This appears to be the size of the security
7915                  * descriptor; the calling sequence of
7916                  * "ZwQuerySecurityObject()" suggests that it would
7917                  * be.  The actual security descriptor wouldn't
7918                  * follow if the max data count in the request
7919                  * was smaller; this lets the client know how
7920                  * big a buffer it needs to provide.
7921                  */
7922                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
7923                 offset += 4;
7924                 break;
7925         case NT_TRANS_GET_USER_QUOTA:
7926                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
7927                         tvb_get_letohl(tvb, offset));
7928                 offset += 4;
7929                 break;
7930         case NT_TRANS_SET_USER_QUOTA:
7931                 /* not decoded yet */
7932                 break;
7933         }
7934
7935         return offset;
7936 }
7937
7938 static int
7939 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
7940                                 int offset, proto_tree *parent_tree,
7941                                 int len, nt_trans_data *ntd _U_)
7942 {
7943         proto_item *item = NULL;
7944         proto_tree *tree = NULL;
7945         smb_info_t *si;
7946         smb_nt_transact_info_t *nti;
7947
7948         si = (smb_info_t *)pinfo->private_data;
7949         if (si->sip != NULL)
7950                 nti = si->sip->extra_info;
7951         else
7952                 nti = NULL;
7953
7954         if(parent_tree){
7955                 if(nti != NULL){
7956                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7957                                 "%s Setup",
7958                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7959                 } else {
7960                         /*
7961                          * We never saw the request to which this is a
7962                          * response.
7963                          */
7964                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7965                                 "Unknown NT Transaction Setup (matching request not seen)");
7966                 }
7967                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7968         }
7969
7970         if (nti == NULL) {
7971                 offset += len;
7972                 return offset;
7973         }
7974         switch(nti->subcmd){
7975         case NT_TRANS_CREATE:
7976                 break;
7977         case NT_TRANS_IOCTL:
7978                 break;
7979         case NT_TRANS_SSD:
7980                 break;
7981         case NT_TRANS_NOTIFY:
7982                 break;
7983         case NT_TRANS_RENAME:
7984                 /* XXX not documented */
7985                 break;
7986         case NT_TRANS_QSD:
7987                 break;
7988         case NT_TRANS_GET_USER_QUOTA:
7989                 /* not decoded yet */
7990                 break;
7991         case NT_TRANS_SET_USER_QUOTA:
7992                 /* not decoded yet */
7993                 break;
7994         }
7995
7996         return offset;
7997 }
7998
7999 static int
8000 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8001 {
8002         guint8 wc, sc;
8003         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8004         guint32 td=0, tp=0;
8005         smb_info_t *si;
8006         smb_nt_transact_info_t *nti;
8007         static nt_trans_data ntd;
8008         guint16 bc;
8009         int padcnt;
8010         fragment_data *r_fd = NULL;
8011         tvbuff_t *pd_tvb=NULL;
8012         gboolean save_fragmented;
8013
8014         si = (smb_info_t *)pinfo->private_data;
8015         if (si->sip != NULL)
8016                 nti = si->sip->extra_info;
8017         else
8018                 nti = NULL;
8019
8020         /* primary request */
8021         if(nti != NULL){
8022                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8023                 if(check_col(pinfo->cinfo, COL_INFO)){
8024                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8025                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8026                 }
8027         } else {
8028                 proto_tree_add_text(tree, tvb, offset, 0,
8029                         "Function: <unknown function - could not find matching request>");
8030                 if(check_col(pinfo->cinfo, COL_INFO)){
8031                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8032                 }
8033         }
8034
8035         WORD_COUNT;
8036
8037         /* 3 reserved bytes */
8038         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8039         offset += 3;
8040
8041         /* total param count */
8042         tp = tvb_get_letohl(tvb, offset);
8043         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8044         offset += 4;
8045
8046         /* total data count */
8047         td = tvb_get_letohl(tvb, offset);
8048         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8049         offset += 4;
8050
8051         /* param count */
8052         pc = tvb_get_letohl(tvb, offset);
8053         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8054         offset += 4;
8055
8056         /* param offset */
8057         po = tvb_get_letohl(tvb, offset);
8058         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8059         offset += 4;
8060
8061         /* param displacement */
8062         pd = tvb_get_letohl(tvb, offset);
8063         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8064         offset += 4;
8065
8066         /* data count */
8067         dc = tvb_get_letohl(tvb, offset);
8068         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8069         offset += 4;
8070
8071         /* data offset */
8072         od = tvb_get_letohl(tvb, offset);
8073         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8074         offset += 4;
8075
8076         /* data displacement */
8077         dd = tvb_get_letohl(tvb, offset);
8078         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8079         offset += 4;
8080
8081         /* setup count */
8082         sc = tvb_get_guint8(tvb, offset);
8083         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8084         offset += 1;
8085
8086         /* setup data */
8087         if(sc){
8088                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8089                 offset += sc*2;
8090         }
8091
8092         BYTE_COUNT;
8093
8094         /* reassembly of SMB NT Transaction data payload.
8095            In this section we do reassembly of both the data and parameters
8096            blocks of the SMB transaction command.
8097         */
8098         save_fragmented = pinfo->fragmented;
8099         /* do we need reassembly? */
8100         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8101                 /* oh yeah, either data or parameter section needs
8102                    reassembly...
8103                 */
8104                 pinfo->fragmented = TRUE;
8105                 if(smb_trans_reassembly){
8106                         /* ...and we were told to do reassembly */
8107                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8108                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8109                                                              po, pc, pd, td+tp);
8110
8111                         }
8112                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8113                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8114                                                              od, dc, dd+tp, td+tp);
8115                         }
8116                 }
8117         }
8118
8119         /* if we got a reassembled fd structure from the reassembly routine we
8120            must create pd_tvb from it
8121         */
8122         if(r_fd){
8123                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8124                                              r_fd->datalen);
8125                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8126                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8127
8128                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8129         }
8130
8131
8132         if(pd_tvb){
8133           /* we have reassembled data, grab param and data from there */
8134           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8135                                           &ntd, (guint16) tvb_length(pd_tvb));
8136           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8137         } else {
8138           /* we do not have reassembled data, just use what we have in the
8139              packet as well as we can */
8140           /* parameters */
8141           if(po>(guint32)offset){
8142             /* We have some initial padding bytes.
8143              */
8144             padcnt = po-offset;
8145             if (padcnt > bc)
8146               padcnt = bc;
8147             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8148             COUNT_BYTES(padcnt);
8149           }
8150           if(pc){
8151             CHECK_BYTE_COUNT(pc);
8152             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8153             COUNT_BYTES(pc);
8154           }
8155
8156           /* data */
8157           if(od>(guint32)offset){
8158             /* We have some initial padding bytes.
8159              */
8160             padcnt = od-offset;
8161             if (padcnt > bc)
8162               padcnt = bc;
8163             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8164             COUNT_BYTES(padcnt);
8165           }
8166           if(dc){
8167             CHECK_BYTE_COUNT(dc);
8168             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8169             COUNT_BYTES(dc);
8170           }
8171         }
8172         pinfo->fragmented = save_fragmented;
8173
8174         END_OF_SMB
8175
8176         return offset;
8177 }
8178
8179 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8180    NT Transaction command  ends here
8181    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8182
8183 static const value_string print_mode_vals[] = {
8184         {0,     "Text Mode"},
8185         {1,     "Graphics Mode"},
8186         {0, NULL}
8187 };
8188
8189 static int
8190 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8191 {
8192         smb_info_t *si = pinfo->private_data;
8193         int fn_len;
8194         const char *fn;
8195         guint8 wc;
8196         guint16 bc;
8197
8198         WORD_COUNT;
8199
8200         /* setup len */
8201         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8202         offset += 2;
8203
8204         /* print mode */
8205         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8206         offset += 2;
8207
8208         BYTE_COUNT;
8209
8210         /* buffer format */
8211         CHECK_BYTE_COUNT(1);
8212         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8213         COUNT_BYTES(1);
8214
8215         /* print identifier */
8216         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8217         if (fn == NULL)
8218                 goto endofcommand;
8219         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8220                 fn);
8221         COUNT_BYTES(fn_len);
8222
8223         END_OF_SMB
8224
8225         return offset;
8226 }
8227
8228
8229 static int
8230 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8231 {
8232         int cnt;
8233         guint8 wc;
8234         guint16 bc, fid;
8235
8236         WORD_COUNT;
8237
8238         /* fid */
8239         fid = tvb_get_letohs(tvb, offset);
8240         add_fid(tvb, pinfo, tree, offset, 2, fid);
8241         offset += 2;
8242
8243         BYTE_COUNT;
8244
8245         /* buffer format */
8246         CHECK_BYTE_COUNT(1);
8247         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8248         COUNT_BYTES(1);
8249
8250         /* data len */
8251         CHECK_BYTE_COUNT(2);
8252         cnt = tvb_get_letohs(tvb, offset);
8253         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8254         COUNT_BYTES(2);
8255
8256         /* file data */
8257         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
8258
8259         END_OF_SMB
8260
8261         return offset;
8262 }
8263
8264
8265 static const value_string print_status_vals[] = {
8266         {1,     "Held or Stopped"},
8267         {2,     "Printing"},
8268         {3,     "Awaiting print"},
8269         {4,     "In intercept"},
8270         {5,     "File had error"},
8271         {6,     "Printer error"},
8272         {0, NULL}
8273 };
8274
8275 static int
8276 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8277 {
8278         guint8 wc;
8279         guint16 bc;
8280
8281         WORD_COUNT;
8282
8283         /* max count */
8284         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8285         offset += 2;
8286
8287         /* start index */
8288         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8289         offset += 2;
8290
8291         BYTE_COUNT;
8292
8293         END_OF_SMB
8294
8295         return offset;
8296 }
8297
8298 static int
8299 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8300     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8301 {
8302         proto_item *item = NULL;
8303         proto_tree *tree = NULL;
8304         smb_info_t *si = pinfo->private_data;
8305         int fn_len;
8306         const char *fn;
8307
8308         if(parent_tree){
8309                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8310                         "Queue entry");
8311                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8312         }
8313
8314         /* queued time */
8315         CHECK_BYTE_COUNT_SUBR(4);
8316         offset = dissect_smb_datetime(tvb, tree, offset,
8317                 hf_smb_print_queue_date,
8318                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8319         *bcp -= 4;
8320
8321         /* status */
8322         CHECK_BYTE_COUNT_SUBR(1);
8323         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8324         COUNT_BYTES_SUBR(1);
8325
8326         /* spool file number */
8327         CHECK_BYTE_COUNT_SUBR(2);
8328         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8329         COUNT_BYTES_SUBR(2);
8330
8331         /* spool file size */
8332         CHECK_BYTE_COUNT_SUBR(4);
8333         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8334         COUNT_BYTES_SUBR(4);
8335
8336         /* reserved byte */
8337         CHECK_BYTE_COUNT_SUBR(1);
8338         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8339         COUNT_BYTES_SUBR(1);
8340
8341         /* file name */
8342         fn_len = 16;
8343         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
8344         CHECK_STRING_SUBR(fn);
8345         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8346                 fn);
8347         COUNT_BYTES_SUBR(fn_len);
8348
8349         *trunc = FALSE;
8350         return offset;
8351 }
8352
8353 static int
8354 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8355 {
8356         guint16 cnt=0, len;
8357         guint8 wc;
8358         guint16 bc;
8359         gboolean trunc;
8360
8361         WORD_COUNT;
8362
8363         /* count */
8364         cnt = tvb_get_letohs(tvb, offset);
8365         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8366         offset += 2;
8367
8368         /* restart index */
8369         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8370         offset += 2;
8371
8372         BYTE_COUNT;
8373
8374         /* buffer format */
8375         CHECK_BYTE_COUNT(1);
8376         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8377         COUNT_BYTES(1);
8378
8379         /* data len */
8380         CHECK_BYTE_COUNT(2);
8381         len = tvb_get_letohs(tvb, offset);
8382         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8383         COUNT_BYTES(2);
8384
8385         /* queue elements */
8386         while(cnt--){
8387                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8388                     &bc, &trunc);
8389                 if (trunc)
8390                         goto endofcommand;
8391         }
8392
8393         END_OF_SMB
8394
8395         return offset;
8396 }
8397
8398
8399 static int
8400 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8401 {
8402         int name_len;
8403         guint16 bc;
8404         guint8 wc;
8405         guint16 message_len;
8406
8407         WORD_COUNT;
8408
8409         BYTE_COUNT;
8410
8411         /* buffer format */
8412         CHECK_BYTE_COUNT(1);
8413         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8414         COUNT_BYTES(1);
8415
8416         /* originator name */
8417         /* XXX - what if this runs past bc? */
8418         name_len = tvb_strsize(tvb, offset);
8419         CHECK_BYTE_COUNT(name_len);
8420         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8421             name_len, TRUE);
8422         COUNT_BYTES(name_len);
8423
8424         /* buffer format */
8425         CHECK_BYTE_COUNT(1);
8426         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8427         COUNT_BYTES(1);
8428
8429         /* destination name */
8430         /* XXX - what if this runs past bc? */
8431         name_len = tvb_strsize(tvb, offset);
8432         CHECK_BYTE_COUNT(name_len);
8433         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8434             name_len, TRUE);
8435         COUNT_BYTES(name_len);
8436
8437         /* buffer format */
8438         CHECK_BYTE_COUNT(1);
8439         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8440         COUNT_BYTES(1);
8441
8442         /* message len */
8443         CHECK_BYTE_COUNT(2);
8444         message_len = tvb_get_letohs(tvb, offset);
8445         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8446             message_len);
8447         COUNT_BYTES(2);
8448
8449         /* message */
8450         CHECK_BYTE_COUNT(message_len);
8451         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8452             TRUE);
8453         COUNT_BYTES(message_len);
8454
8455         END_OF_SMB
8456
8457         return offset;
8458 }
8459
8460 static int
8461 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8462 {
8463         int name_len;
8464         guint16 bc;
8465         guint8 wc;
8466
8467         WORD_COUNT;
8468
8469         BYTE_COUNT;
8470
8471         /* buffer format */
8472         CHECK_BYTE_COUNT(1);
8473         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8474         COUNT_BYTES(1);
8475
8476         /* originator name */
8477         /* XXX - what if this runs past bc? */
8478         name_len = tvb_strsize(tvb, offset);
8479         CHECK_BYTE_COUNT(name_len);
8480         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8481             name_len, TRUE);
8482         COUNT_BYTES(name_len);
8483
8484         /* buffer format */
8485         CHECK_BYTE_COUNT(1);
8486         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8487         COUNT_BYTES(1);
8488
8489         /* destination name */
8490         /* XXX - what if this runs past bc? */
8491         name_len = tvb_strsize(tvb, offset);
8492         CHECK_BYTE_COUNT(name_len);
8493         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8494             name_len, TRUE);
8495         COUNT_BYTES(name_len);
8496
8497         END_OF_SMB
8498
8499         return offset;
8500 }
8501
8502 static int
8503 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8504 {
8505         guint16 bc;
8506         guint8 wc;
8507
8508         WORD_COUNT;
8509
8510         /* message group ID */
8511         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
8512         offset += 2;
8513
8514         BYTE_COUNT;
8515
8516         END_OF_SMB
8517
8518         return offset;
8519 }
8520
8521 static int
8522 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8523 {
8524         guint16 bc;
8525         guint8 wc;
8526         guint16 message_len;
8527
8528         WORD_COUNT;
8529
8530         BYTE_COUNT;
8531
8532         /* buffer format */
8533         CHECK_BYTE_COUNT(1);
8534         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8535         COUNT_BYTES(1);
8536
8537         /* message len */
8538         CHECK_BYTE_COUNT(2);
8539         message_len = tvb_get_letohs(tvb, offset);
8540         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8541             message_len);
8542         COUNT_BYTES(2);
8543
8544         /* message */
8545         CHECK_BYTE_COUNT(message_len);
8546         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8547             TRUE);
8548         COUNT_BYTES(message_len);
8549
8550         END_OF_SMB
8551
8552         return offset;
8553 }
8554
8555 static int
8556 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8557 {
8558         int name_len;
8559         guint16 bc;
8560         guint8 wc;
8561
8562         WORD_COUNT;
8563
8564         BYTE_COUNT;
8565
8566         /* buffer format */
8567         CHECK_BYTE_COUNT(1);
8568         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8569         COUNT_BYTES(1);
8570
8571         /* forwarded name */
8572         /* XXX - what if this runs past bc? */
8573         name_len = tvb_strsize(tvb, offset);
8574         CHECK_BYTE_COUNT(name_len);
8575         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
8576             name_len, TRUE);
8577         COUNT_BYTES(name_len);
8578
8579         END_OF_SMB
8580
8581         return offset;
8582 }
8583
8584 static int
8585 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8586 {
8587         int name_len;
8588         guint16 bc;
8589         guint8 wc;
8590
8591         WORD_COUNT;
8592
8593         BYTE_COUNT;
8594
8595         /* buffer format */
8596         CHECK_BYTE_COUNT(1);
8597         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8598         COUNT_BYTES(1);
8599
8600         /* machine name */
8601         /* XXX - what if this runs past bc? */
8602         name_len = tvb_strsize(tvb, offset);
8603         CHECK_BYTE_COUNT(name_len);
8604         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
8605             name_len, TRUE);
8606         COUNT_BYTES(name_len);
8607
8608         END_OF_SMB
8609
8610         return offset;
8611 }
8612
8613
8614 static int
8615 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8616 {
8617         guint8  wc, cmd=0xff;
8618         guint16 andxoffset=0;
8619         guint16 bc;
8620         smb_info_t *si = pinfo->private_data;
8621         int fn_len;
8622         const char *fn;
8623
8624         WORD_COUNT;
8625
8626         /* next smb command */
8627         cmd = tvb_get_guint8(tvb, offset);
8628         if(cmd!=0xff){
8629                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8630         } else {
8631                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
8632         }
8633         offset += 1;
8634
8635         /* reserved byte */
8636         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8637         offset += 1;
8638
8639         /* andxoffset */
8640         andxoffset = tvb_get_letohs(tvb, offset);
8641         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8642         offset += 2;
8643
8644         /* reserved byte */
8645         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8646         offset += 1;
8647
8648         /* file name len */
8649         fn_len = tvb_get_letohs(tvb, offset);
8650         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8651         offset += 2;
8652
8653         /* Create flags */
8654         offset = dissect_nt_create_bits(tvb, tree, offset);
8655
8656         /* root directory fid */
8657         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8658         offset += 4;
8659
8660         /* nt access mask */
8661         offset = dissect_smb_access_mask(tvb, tree, offset);
8662
8663         /* allocation size */
8664         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8665         offset += 8;
8666
8667         /* Extended File Attributes */
8668         offset = dissect_file_ext_attr(tvb, tree, offset);
8669
8670         /* share access */
8671         offset = dissect_nt_share_access(tvb, tree, offset);
8672
8673         /* create disposition */
8674         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8675         offset += 4;
8676
8677         /* create options */
8678         offset = dissect_nt_create_options(tvb, tree, offset);
8679
8680         /* impersonation level */
8681         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8682         offset += 4;
8683
8684         /* security flags */
8685         offset = dissect_nt_security_flags(tvb, tree, offset);
8686
8687         BYTE_COUNT;
8688
8689         /* file name */
8690         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
8691         if (fn == NULL)
8692                 goto endofcommand;
8693         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8694                 fn);
8695         COUNT_BYTES(fn_len);
8696
8697         if (check_col(pinfo->cinfo, COL_INFO)) {
8698                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8699                     format_text(fn, strlen(fn)));
8700         }
8701
8702         END_OF_SMB
8703
8704         /* call AndXCommand (if there are any) */
8705         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
8706
8707         return offset;
8708 }
8709
8710
8711 static int
8712 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8713 {
8714         guint8  wc, cmd=0xff;
8715         guint16 andxoffset=0;
8716         guint16 bc;
8717         guint16 fid;
8718
8719         WORD_COUNT;
8720
8721         /* next smb command */
8722         cmd = tvb_get_guint8(tvb, offset);
8723         if(cmd!=0xff){
8724                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8725         } else {
8726                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
8727         }
8728         offset += 1;
8729
8730         /* reserved byte */
8731         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8732         offset += 1;
8733
8734         /* andxoffset */
8735         andxoffset = tvb_get_letohs(tvb, offset);
8736         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8737         offset += 2;
8738
8739         /* oplock level */
8740         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8741         offset += 1;
8742
8743         /* fid */
8744         fid = tvb_get_letohs(tvb, offset);
8745         add_fid(tvb, pinfo, tree, offset, 2, fid);
8746         offset += 2;
8747
8748         /* create action */
8749         /*XXX is this really the same as create disposition in the request? it looks so*/
8750         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
8751         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8752         offset += 4;
8753
8754         /* create time */
8755         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
8756
8757         /* access time */
8758         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
8759
8760         /* last write time */
8761         offset = dissect_nt_64bit_time(tvb, tree, offset,
8762                 hf_smb_last_write_time);
8763
8764         /* last change time */
8765         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
8766
8767         /* Extended File Attributes */
8768         offset = dissect_file_ext_attr(tvb, tree, offset);
8769
8770         /* allocation size */
8771         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8772         offset += 8;
8773
8774         /* end of file */
8775         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8776         offset += 8;
8777
8778         /* File Type */
8779         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8780         offset += 2;
8781
8782         /* IPC State */
8783         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8784
8785         /* is directory */
8786         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8787         offset += 1;
8788
8789         BYTE_COUNT;
8790
8791         END_OF_SMB
8792
8793         /* call AndXCommand (if there are any) */
8794         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
8795
8796         return offset;
8797 }
8798
8799
8800 static int
8801 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8802 {
8803         guint8 wc;
8804         guint16 bc;
8805
8806         WORD_COUNT;
8807
8808         BYTE_COUNT;
8809
8810         END_OF_SMB
8811
8812         return offset;
8813 }
8814
8815 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8816    BEGIN Transaction/Transaction2 Primary and secondary requests
8817    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8818
8819
8820 const value_string trans2_cmd_vals[] = {
8821         { 0x00,         "OPEN2" },
8822         { 0x01,         "FIND_FIRST2" },
8823         { 0x02,         "FIND_NEXT2" },
8824         { 0x03,         "QUERY_FS_INFO" },
8825         { 0x04,         "SET_FS_QUOTA" },
8826         { 0x05,         "QUERY_PATH_INFO" },
8827         { 0x06,         "SET_PATH_INFO" },
8828         { 0x07,         "QUERY_FILE_INFO" },
8829         { 0x08,         "SET_FILE_INFO" },
8830         { 0x09,         "FSCTL" },
8831         { 0x0A,         "IOCTL2" },
8832         { 0x0B,         "FIND_NOTIFY_FIRST" },
8833         { 0x0C,         "FIND_NOTIFY_NEXT" },
8834         { 0x0D,         "CREATE_DIRECTORY" },
8835         { 0x0E,         "SESSION_SETUP" },
8836         { 0x10,         "GET_DFS_REFERRAL" },
8837         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
8838         { 0,    NULL }
8839 };
8840
8841 static const true_false_string tfs_tf_dtid = {
8842         "Also DISCONNECT TID",
8843         "Do NOT disconnect TID"
8844 };
8845 static const true_false_string tfs_tf_owt = {
8846         "One Way Transaction (NO RESPONSE)",
8847         "Two way transaction"
8848 };
8849
8850 static const true_false_string tfs_ff2_backup = {
8851         "Find WITH backup intent",
8852         "No backup intent"
8853 };
8854 static const true_false_string tfs_ff2_continue = {
8855         "CONTINUE search from previous position",
8856         "New search, do NOT continue from previous position"
8857 };
8858 static const true_false_string tfs_ff2_resume = {
8859         "Return RESUME keys",
8860         "Do NOT return resume keys"
8861 };
8862 static const true_false_string tfs_ff2_close_eos = {
8863         "CLOSE search if END OF SEARCH is reached",
8864         "Do NOT close search if end of search reached"
8865 };
8866 static const true_false_string tfs_ff2_close = {
8867         "CLOSE search after this request",
8868         "Do NOT close search after this request"
8869 };
8870
8871 /* used by
8872    TRANS2_FIND_FIRST2
8873 */
8874 static const value_string ff2_il_vals[] = {
8875         { 1,            "Info Standard"},
8876         { 2,            "Info Query EA Size"},
8877         { 3,            "Info Query EAs From List"},
8878         { 0x0101,       "Find File Directory Info"},
8879         { 0x0102,       "Find File Full Directory Info"},
8880         { 0x0103,       "Find File Names Info"},
8881         { 0x0104,       "Find File Both Directory Info"},
8882         { 0x0202,       "Find File UNIX"},
8883         {0, NULL}
8884 };
8885
8886 /* values used by :
8887         TRANS2_QUERY_PATH_INFORMATION
8888         TRANS2_QUERY_FILE_INFORMATION
8889 */
8890 static const value_string qpi_loi_vals[] = {
8891         { 1,            "Info Standard"},
8892         { 2,            "Info Query EA Size"},
8893         { 3,            "Info Query EAs From List"},
8894         { 4,            "Info Query All EAs"},
8895         { 6,            "Info Is Name Valid"},
8896         { 0x0101,       "Query File Basic Info"},
8897         { 0x0102,       "Query File Standard Info"},
8898         { 0x0103,       "Query File EA Info"},
8899         { 0x0104,       "Query File Name Info"},
8900         { 0x0107,       "Query File All Info"},
8901         { 0x0108,       "Query File Alt Name Info"},
8902         { 0x0109,       "Query File Stream Info"},
8903         { 0x010b,       "Query File Compression Info"},
8904         { 0x0200,       "Query File Unix Basic"},
8905         { 0x0201,       "Query File Unix Link"},
8906         { 1004,         "Query File Basic Info"},
8907         { 1005,         "Query File Standard Info"},
8908         { 1006,         "Query File Internal Info"},
8909         { 1007,         "Query File EA Info"},
8910         { 1009,         "Query File Name Info"},
8911         { 1010,         "Query File Rename Info"},
8912         { 1011,         "Query File Link Info"},
8913         { 1012,         "Query File Names Info"},
8914         { 1013,         "Query File Disposition Info"},
8915         { 1014,         "Query File Position Info"},
8916         { 1015,         "Query File Full EA Info"},
8917         { 1016,         "Query File Mode Info"},
8918         { 1017,         "Query File Alignment Info"},
8919         { 1018,         "Query File All Info"},
8920         { 1019,         "Query File Allocation Info"},
8921         { 1020,         "Query File End of File Info"},
8922         { 1021,         "Query File Alt Name Info"},
8923         { 1022,         "Query File Stream Info"},
8924         { 1023,         "Query File Pipe Info"},
8925         { 1024,         "Query File Pipe Local Info"},
8926         { 1025,         "Query File Pipe Remote Info"},
8927         { 1026,         "Query File Mailslot Query Info"},
8928         { 1027,         "Query File Mailslot Set Info"},
8929         { 1028,         "Query File Compression Info"},
8930         { 1029,         "Query File ObjectID Info"},
8931         { 1030,         "Query File Completion Info"},
8932         { 1031,         "Query File Move Cluster Info"},
8933         { 1032,         "Query File Quota Info"},
8934         { 1033,         "Query File Reparsepoint Info"},
8935         { 1034,         "Query File Network Open Info"},
8936         { 1035,         "Query File Attribute Tag Info"},
8937         { 1036,         "Query File Tracking Info"},
8938         { 1037,         "Query File Maximum Info"},
8939         {0, NULL}
8940 };
8941
8942 /* values used by :
8943         TRANS2_SET_PATH_INFORMATION
8944         TRANS2_SET_FILE_INFORMATION
8945         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
8946         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
8947         well; note that they're different from the QUERY_PATH_INFORMATION
8948         and QUERY_FILE_INFORMATION values!)
8949 */
8950 static const value_string spi_loi_vals[] = {
8951         { 1,            "Info Standard"},
8952         { 2,            "Info Query EA Size"},
8953         { 4,            "Info Query All EAs"},
8954         { 0x0101,       "Set File Basic Info"},
8955         { 0x0102,       "Set File Disposition Info"},
8956         { 0x0103,       "Set File Allocation Info"},
8957         { 0x0104,       "Set File End Of File Info"},
8958         { 0x0200,       "Set File Unix Basic"},
8959         { 0x0201,       "Set File Unix Link"},
8960         { 0x0202,       "Set File Unix HardLink"},
8961         { 1004,         "Set File Basic Info"},
8962         { 1010,         "Set Rename Information"},
8963         { 1013,         "Set Disposition Information"},
8964         { 1014,         "Set Position Information"},
8965         { 1016,         "Set Mode Information"},
8966         { 1019,         "Set Allocation Information"},
8967         { 1020,         "Set EOF Information"},
8968         { 1023,         "Set File Pipe Information"},
8969         { 1025,         "Set File Pipe Remote Information"},
8970         { 1029,         "Set Copy On Write Information"},
8971         { 1032,         "Set OLE Class ID Information"},
8972         { 1039,         "Set Inherit Context Index Information"},
8973         { 1040,         "Set OLE Information (?)"},
8974         {0, NULL}
8975 };
8976
8977 static const value_string qfsi_vals[] = {
8978         { 1,            "Info Allocation"},
8979         { 2,            "Info Volume"},
8980         { 0x0101,       "Query FS Label Info"},
8981         { 0x0102,       "Query FS Volume Info"},
8982         { 0x0103,       "Query FS Size Info"},
8983         { 0x0104,       "Query FS Device Info"},
8984         { 0x0105,       "Query FS Attribute Info"},
8985         { 0x0200,       "Unix Query FS Info"},
8986         { 0x0301,       "Mac Query FS Info"},
8987         { 1001,         "Query FS Label Info"},
8988         { 1002,         "Query FS Volume Info"},
8989         { 1003,         "Query FS Size Info"},
8990         { 1004,         "Query FS Device Info"},
8991         { 1005,         "Query FS Attribute Info"},
8992         { 1006,         "Query FS Quota Info"},
8993         { 1007,         "Query Full FS Size Info"},
8994         { 1008,         "Object ID Information"},
8995         {0, NULL}
8996 };
8997
8998 static const value_string nt_rename_vals[] = {
8999         { 0x0103,       "Create Hard Link"},
9000         {0, NULL}
9001 };
9002
9003
9004 static const value_string delete_pending_vals[] = {
9005         {0,     "Normal, no pending delete"},
9006         {1,     "This object has DELETE PENDING"},
9007         {0, NULL}
9008 };
9009
9010 static const value_string alignment_vals[] = {
9011         {0,     "Byte alignment"},
9012         {1,     "Word (16bit) alignment"},
9013         {3,     "Long (32bit) alignment"},
9014         {7,     "8 byte boundary alignment"},
9015         {0x0f,  "16 byte boundary alignment"},
9016         {0x1f,  "32 byte boundary alignment"},
9017         {0x3f,  "64 byte boundary alignment"},
9018         {0x7f,  "128 byte boundary alignment"},
9019         {0xff,  "256 byte boundary alignment"},
9020         {0x1ff, "512 byte boundary alignment"},
9021         {0, NULL}
9022 };
9023
9024 static const true_false_string tfs_marked_for_deletion = {
9025         "File is MARKED FOR DELETION",
9026         "File is NOT marked for deletion"
9027 };
9028
9029 static const true_false_string tfs_get_dfs_server_hold_storage = {
9030         "Referral SERVER HOLDS STORAGE for the file",
9031         "Referral server does NOT hold storage for the file"
9032 };
9033 static const true_false_string tfs_get_dfs_fielding = {
9034         "The server in referral is FIELDING CAPABLE",
9035         "The server in referrals is NOT fielding capable"
9036 };
9037
9038 static const true_false_string tfs_dfs_referral_flags_strip = {
9039         "STRIP off pathconsumed characters before submitting",
9040         "Do NOT strip off any characters"
9041 };
9042
9043 static const value_string dfs_referral_server_type_vals[] = {
9044         {0,     "Don't know"},
9045         {1,     "SMB Server"},
9046         {2,     "Netware Server"},
9047         {3,     "Domain Server"},
9048         {0, NULL}
9049 };
9050
9051
9052 static const true_false_string tfs_device_char_removable = {
9053         "This is a REMOVABLE device",
9054         "This is NOT a removable device"
9055 };
9056 static const true_false_string tfs_device_char_read_only = {
9057         "This is a READ-ONLY device",
9058         "This is NOT a read-only device"
9059 };
9060 static const true_false_string tfs_device_char_floppy = {
9061         "This is a FLOPPY DISK device",
9062         "This is NOT a floppy disk device"
9063 };
9064 static const true_false_string tfs_device_char_write_once = {
9065         "This is a WRITE-ONCE device",
9066         "This is NOT a write-once device"
9067 };
9068 static const true_false_string tfs_device_char_remote = {
9069         "This is a REMOTE device",
9070         "This is NOT a remote device"
9071 };
9072 static const true_false_string tfs_device_char_mounted = {
9073         "This device is MOUNTED",
9074         "This device is NOT mounted"
9075 };
9076 static const true_false_string tfs_device_char_virtual = {
9077         "This is a VIRTUAL device",
9078         "This is NOT a virtual device"
9079 };
9080
9081
9082 static const true_false_string tfs_fs_attr_css = {
9083         "This FS supports CASE SENSITIVE SEARCHes",
9084         "This FS does NOT support case sensitive searches"
9085 };
9086 static const true_false_string tfs_fs_attr_cpn = {
9087         "This FS supports CASE PRESERVED NAMES",
9088         "This FS does NOT support case preserved names"
9089 };
9090 static const true_false_string tfs_fs_attr_uod = {
9091         "This FS supports UNICODE NAMES",
9092         "This FS does NOT support unicode names"
9093 };
9094 static const true_false_string tfs_fs_attr_pacls = {
9095         "This FS supports PERSISTENT ACLs",
9096         "This FS does NOT support persistent acls"
9097 };
9098 static const true_false_string tfs_fs_attr_fc = {
9099         "This FS supports COMPRESSED FILES",
9100         "This FS does NOT support compressed files"
9101 };
9102 static const true_false_string tfs_fs_attr_vq = {
9103         "This FS supports VOLUME QUOTAS",
9104         "This FS does NOT support volume quotas"
9105 };
9106 static const true_false_string tfs_fs_attr_srp = {
9107         "This FS supports REPARSE POINTS",
9108         "This FS does NOT support reparse points"
9109 };
9110 static const true_false_string tfs_fs_attr_srs = {
9111         "This FS supports REMOTE STORAGE",
9112         "This FS does NOT support remote storage"
9113 };
9114 static const true_false_string tfs_fs_attr_ssf = {
9115         "This FS supports SPARSE FILES",
9116         "This FS does NOT support sparse files"
9117 };
9118 static const true_false_string tfs_fs_attr_sla = {
9119         "This FS supports LFN APIs",
9120         "This FS does NOT support lfn apis"
9121 };
9122 static const true_false_string tfs_fs_attr_vic = {
9123         "This FS VOLUME IS COMPRESSED",
9124         "This FS volume is NOT compressed"
9125 };
9126 static const true_false_string tfs_fs_attr_soids = {
9127         "This FS supports OIDs",
9128         "This FS does NOT support OIDs"
9129 };
9130 static const true_false_string tfs_fs_attr_se = {
9131         "This FS supports ENCRYPTION",
9132         "This FS does NOT support encryption"
9133 };
9134 static const true_false_string tfs_fs_attr_ns = {
9135         "This FS supports NAMED STREAMS",
9136         "This FS does NOT support named streams"
9137 };
9138 static const true_false_string tfs_fs_attr_rov = {
9139         "This is a READ ONLY VOLUME",
9140         "This is a read/write volume"
9141 };
9142
9143 #define FF2_RESUME      0x0004
9144
9145 static int
9146 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9147 {
9148         guint16 mask;
9149         proto_item *item = NULL;
9150         proto_tree *tree = NULL;
9151         smb_info_t *si;
9152         smb_transact2_info_t *t2i;
9153
9154         mask = tvb_get_letohs(tvb, offset);
9155
9156         si = (smb_info_t *)pinfo->private_data;
9157         if (si->sip != NULL) {
9158                 t2i = si->sip->extra_info;
9159                 if (t2i != NULL) {
9160                         if (!pinfo->fd->flags.visited)
9161                                 t2i->resume_keys = (mask & FF2_RESUME);
9162                 }
9163         }
9164
9165         if(parent_tree){
9166                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9167                         "Flags: 0x%04x", mask);
9168                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9169         }
9170
9171         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9172                 tvb, offset, 2, mask);
9173         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9174                 tvb, offset, 2, mask);
9175         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9176                 tvb, offset, 2, mask);
9177         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9178                 tvb, offset, 2, mask);
9179         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9180                 tvb, offset, 2, mask);
9181
9182         offset += 2;
9183
9184         return offset;
9185 }
9186
9187 #if 0
9188 static int
9189 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9190 {
9191         guint16 mask;
9192         proto_item *item = NULL;
9193         proto_tree *tree = NULL;
9194
9195         mask = tvb_get_letohs(tvb, offset);
9196
9197         if(parent_tree){
9198                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9199                         "IO Flag: 0x%04x", mask);
9200                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9201         }
9202
9203         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9204                 tvb, offset, 2, mask);
9205         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9206                 tvb, offset, 2, mask);
9207
9208         offset += 2;
9209
9210         return offset;
9211 }
9212 #endif
9213
9214 static int
9215 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9216     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9217 {
9218         proto_item *item = NULL;
9219         proto_tree *tree = NULL;
9220         smb_info_t *si;
9221         smb_transact2_info_t *t2i;
9222         int fn_len;
9223         const char *fn;
9224
9225         si = (smb_info_t *)pinfo->private_data;
9226         if (si->sip != NULL)
9227                 t2i = si->sip->extra_info;
9228         else
9229                 t2i = NULL;
9230
9231         if(parent_tree){
9232                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9233                                 "%s Parameters",
9234                                 val_to_str(subcmd, trans2_cmd_vals,
9235                                            "Unknown (0x%02x)"));
9236                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9237         }
9238
9239         switch(subcmd){
9240         case 0x00:      /*TRANS2_OPEN2*/
9241                 /* open flags */
9242                 CHECK_BYTE_COUNT_TRANS(2);
9243                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9244                 bc -= 2;
9245
9246                 /* desired access */
9247                 CHECK_BYTE_COUNT_TRANS(2);
9248                 offset = dissect_access(tvb, tree, offset, "Desired");
9249                 bc -= 2;
9250
9251                 /* Search Attributes */
9252                 CHECK_BYTE_COUNT_TRANS(2);
9253                 offset = dissect_search_attributes(tvb, tree, offset);
9254                 bc -= 2;
9255
9256                 /* File Attributes */
9257                 CHECK_BYTE_COUNT_TRANS(2);
9258                 offset = dissect_file_attributes(tvb, tree, offset, 2);
9259                 bc -= 2;
9260
9261                 /* create time */
9262                 CHECK_BYTE_COUNT_TRANS(4);
9263                 offset = dissect_smb_datetime(tvb, tree, offset,
9264                         hf_smb_create_time,
9265                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9266                         TRUE);
9267                 bc -= 4;
9268
9269                 /* open function */
9270                 CHECK_BYTE_COUNT_TRANS(2);
9271                 offset = dissect_open_function(tvb, tree, offset);
9272                 bc -= 2;
9273
9274                 /* allocation size */
9275                 CHECK_BYTE_COUNT_TRANS(4);
9276                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9277                 COUNT_BYTES_TRANS(4);
9278
9279                 /* 10 reserved bytes */
9280                 CHECK_BYTE_COUNT_TRANS(10);
9281                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9282                 COUNT_BYTES_TRANS(10);
9283
9284                 /* file name */
9285                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9286                 CHECK_STRING_TRANS(fn);
9287                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9288                         fn);
9289                 COUNT_BYTES_TRANS(fn_len);
9290
9291                 if (check_col(pinfo->cinfo, COL_INFO)) {
9292                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9293                             format_text(fn, strlen(fn)));
9294                 }
9295                 break;
9296         case 0x01:      /*TRANS2_FIND_FIRST2*/
9297                 /* Search Attributes */
9298                 CHECK_BYTE_COUNT_TRANS(2);
9299                 offset = dissect_search_attributes(tvb, tree, offset);
9300                 bc -= 2;
9301
9302                 /* search count */
9303                 CHECK_BYTE_COUNT_TRANS(2);
9304                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9305                 COUNT_BYTES_TRANS(2);
9306
9307                 /* Find First2 flags */
9308                 CHECK_BYTE_COUNT_TRANS(2);
9309                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9310                 bc -= 2;
9311
9312                 /* Find First2 information level */
9313                 CHECK_BYTE_COUNT_TRANS(2);
9314                 si->info_level = tvb_get_letohs(tvb, offset);
9315                 if (!pinfo->fd->flags.visited)
9316                         t2i->info_level = si->info_level;
9317                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9318                 COUNT_BYTES_TRANS(2);
9319
9320                 /* storage type */
9321                 CHECK_BYTE_COUNT_TRANS(4);
9322                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9323                 COUNT_BYTES_TRANS(4);
9324
9325                 /* search pattern */
9326                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9327                 CHECK_STRING_TRANS(fn);
9328                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9329                         fn);
9330                 COUNT_BYTES_TRANS(fn_len);
9331
9332                 if (check_col(pinfo->cinfo, COL_INFO)) {
9333                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9334                             format_text(fn, strlen(fn)));
9335                 }
9336
9337                 break;
9338         case 0x02:      /*TRANS2_FIND_NEXT2*/
9339                 /* sid */
9340                 CHECK_BYTE_COUNT_TRANS(2);
9341                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
9342                 COUNT_BYTES_TRANS(2);
9343
9344                 /* search count */
9345                 CHECK_BYTE_COUNT_TRANS(2);
9346                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9347                 COUNT_BYTES_TRANS(2);
9348
9349                 /* Find First2 information level */
9350                 CHECK_BYTE_COUNT_TRANS(2);
9351                 si->info_level = tvb_get_letohs(tvb, offset);
9352                 if (!pinfo->fd->flags.visited)
9353                         t2i->info_level = si->info_level;
9354                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9355                 COUNT_BYTES_TRANS(2);
9356
9357                 /* resume key */
9358                 CHECK_BYTE_COUNT_TRANS(4);
9359                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9360                 COUNT_BYTES_TRANS(4);
9361
9362                 /* Find First2 flags */
9363                 CHECK_BYTE_COUNT_TRANS(2);
9364                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9365                 bc -= 2;
9366
9367                 /* file name */
9368                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9369                 CHECK_STRING_TRANS(fn);
9370                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9371                         fn);
9372                 COUNT_BYTES_TRANS(fn_len);
9373
9374                 if (check_col(pinfo->cinfo, COL_INFO)) {
9375                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9376                             format_text(fn, strlen(fn)));
9377                 }
9378
9379                 break;
9380         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9381                 /* level of interest */
9382                 CHECK_BYTE_COUNT_TRANS(2);
9383                 si->info_level = tvb_get_letohs(tvb, offset);
9384                 if (!pinfo->fd->flags.visited)
9385                         t2i->info_level = si->info_level;
9386                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9387                 COUNT_BYTES_TRANS(2);
9388
9389                 if (check_col(pinfo->cinfo, COL_INFO))
9390                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9391                                         val_to_str(si->info_level, qfsi_vals, 
9392                                                    "Unknown (0x%02x)"));
9393
9394                 break;
9395         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9396                 /* level of interest */
9397                 CHECK_BYTE_COUNT_TRANS(2);
9398                 si->info_level = tvb_get_letohs(tvb, offset);
9399                 if (!pinfo->fd->flags.visited)
9400                         t2i->info_level = si->info_level;
9401                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9402                 COUNT_BYTES_TRANS(2);
9403
9404                 if (check_col(pinfo->cinfo, COL_INFO)) {
9405                         col_append_fstr(
9406                                 pinfo->cinfo, COL_INFO, ", %s", 
9407                                 val_to_str(si->info_level, qpi_loi_vals, 
9408                                            "Unknown (%u)"));
9409                 }
9410
9411                 /* 4 reserved bytes */
9412                 CHECK_BYTE_COUNT_TRANS(4);
9413                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9414                 COUNT_BYTES_TRANS(4);
9415
9416                 /* file name */
9417                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9418                 CHECK_STRING_TRANS(fn);
9419                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9420                         fn);
9421                 COUNT_BYTES_TRANS(fn_len);
9422
9423                 if (check_col(pinfo->cinfo, COL_INFO)) {
9424                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9425                             format_text(fn, strlen(fn)));
9426                 }
9427
9428                 break;
9429         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9430                 /* level of interest */
9431                 CHECK_BYTE_COUNT_TRANS(2);
9432                 si->info_level = tvb_get_letohs(tvb, offset);
9433                 if (!pinfo->fd->flags.visited)
9434                         t2i->info_level = si->info_level;
9435                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
9436                 COUNT_BYTES_TRANS(2);
9437
9438                 /* 4 reserved bytes */
9439                 CHECK_BYTE_COUNT_TRANS(4);
9440                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9441                 COUNT_BYTES_TRANS(4);
9442
9443                 /* file name */
9444                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9445                 CHECK_STRING_TRANS(fn);
9446                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9447                         fn);
9448                 COUNT_BYTES_TRANS(fn_len);
9449
9450                 if (check_col(pinfo->cinfo, COL_INFO)) {
9451                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9452                             format_text(fn, strlen(fn)));
9453                 }
9454
9455                 break;
9456         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9457                 guint16 fid;
9458
9459                 /* fid */
9460                 CHECK_BYTE_COUNT_TRANS(2);
9461                 fid = tvb_get_letohs(tvb, offset);
9462                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9463                 COUNT_BYTES_TRANS(2);
9464
9465                 /* level of interest */
9466                 CHECK_BYTE_COUNT_TRANS(2);
9467                 si->info_level = tvb_get_letohs(tvb, offset);
9468                 if (!pinfo->fd->flags.visited)
9469                         t2i->info_level = si->info_level;
9470                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9471                 COUNT_BYTES_TRANS(2);
9472
9473                 if (check_col(pinfo->cinfo, COL_INFO)) {
9474                         col_append_fstr(
9475                                 pinfo->cinfo, COL_INFO, ", %s", 
9476                                 val_to_str(si->info_level, qpi_loi_vals, 
9477                                            "Unknown (%u)"));
9478                 }
9479
9480                 break;
9481         }
9482         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9483                 guint16 fid;
9484
9485                 /* fid */
9486                 CHECK_BYTE_COUNT_TRANS(2);
9487                 fid = tvb_get_letohs(tvb, offset);
9488                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9489                 COUNT_BYTES_TRANS(2);
9490
9491                 /* level of interest */
9492                 CHECK_BYTE_COUNT_TRANS(2);
9493                 si->info_level = tvb_get_letohs(tvb, offset);
9494                 if (!pinfo->fd->flags.visited)
9495                         t2i->info_level = si->info_level;
9496                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
9497                 COUNT_BYTES_TRANS(2);
9498
9499 #if 0
9500                 /*
9501                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9502                  * Extensions Version 3.0, Document Version 1.11,
9503                  * July 19, 1990" says this is I/O flags, but it's
9504                  * reserved in the SNIA spec, and some clients appear
9505                  * to leave junk in it.
9506                  *
9507                  * Is this some field used only if a particular
9508                  * dialect was negotiated, so that clients can feel
9509                  * safe not setting it if they haven't negotiated that
9510                  * dialect?  Or do the (non-OS/2) clients simply not care
9511                  * about that particular OS/2-oriented dialect?
9512                  */
9513
9514                 /* IO Flag */
9515                 CHECK_BYTE_COUNT_TRANS(2);
9516                 offset = dissect_sfi_ioflag(tvb, tree, offset);
9517                 bc -= 2;
9518 #else
9519                 /* 2 reserved bytes */
9520                 CHECK_BYTE_COUNT_TRANS(2);
9521                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9522                 COUNT_BYTES_TRANS(2);
9523 #endif
9524
9525                 break;
9526         }
9527         case 0x09:      /*TRANS2_FSCTL*/
9528                 /* this call has no parameter block in the request */
9529
9530                 /*
9531                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9532                  * Extensions Version 3.0, Document Version 1.11,
9533                  * July 19, 1990" says this this contains a
9534                  * "File system specific parameter block".  (That means
9535                  * we may not be able to dissect it in any case.)
9536                  */
9537                 break;
9538         case 0x0a:      /*TRANS2_IOCTL2*/
9539                 /* this call has no parameter block in the request */
9540
9541                 /*
9542                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9543                  * Extensions Version 3.0, Document Version 1.11,
9544                  * July 19, 1990" says this this contains a
9545                  * "Device/function specific parameter block".  (That
9546                  * means we may not be able to dissect it in any case.)
9547                  */
9548                 break;
9549         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
9550                 /* Search Attributes */
9551                 CHECK_BYTE_COUNT_TRANS(2);
9552                 offset = dissect_search_attributes(tvb, tree, offset);
9553                 bc -= 2;
9554
9555                 /* Number of changes to wait for */
9556                 CHECK_BYTE_COUNT_TRANS(2);
9557                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9558                 COUNT_BYTES_TRANS(2);
9559
9560                 /* Find Notify information level */
9561                 CHECK_BYTE_COUNT_TRANS(2);
9562                 si->info_level = tvb_get_letohs(tvb, offset);
9563                 if (!pinfo->fd->flags.visited)
9564                         t2i->info_level = si->info_level;
9565                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
9566                 COUNT_BYTES_TRANS(2);
9567
9568                 /* 4 reserved bytes */
9569                 CHECK_BYTE_COUNT_TRANS(4);
9570                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9571                 COUNT_BYTES_TRANS(4);
9572
9573                 /* file name */
9574                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9575                 CHECK_STRING_TRANS(fn);
9576                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9577                         fn);
9578                 COUNT_BYTES_TRANS(fn_len);
9579
9580                 if (check_col(pinfo->cinfo, COL_INFO)) {
9581                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9582                             format_text(fn, strlen(fn)));
9583                 }
9584
9585                 break;
9586         }
9587         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
9588                 /* Monitor handle */
9589                 CHECK_BYTE_COUNT_TRANS(2);
9590                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
9591                 COUNT_BYTES_TRANS(2);
9592
9593                 /* Number of changes to wait for */
9594                 CHECK_BYTE_COUNT_TRANS(2);
9595                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9596                 COUNT_BYTES_TRANS(2);
9597
9598                 break;
9599         }
9600         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9601                 /* 4 reserved bytes */
9602                 CHECK_BYTE_COUNT_TRANS(4);
9603                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9604                 COUNT_BYTES_TRANS(4);
9605
9606                 /* dir name */
9607                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
9608                         FALSE, FALSE, &bc);
9609                 CHECK_STRING_TRANS(fn);
9610                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9611                         fn);
9612                 COUNT_BYTES_TRANS(fn_len);
9613
9614                 if (check_col(pinfo->cinfo, COL_INFO)) {
9615                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9616                             format_text(fn, strlen(fn)));
9617                 }
9618                 break;
9619         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9620                 /* XXX unknown structure*/
9621                 break;
9622         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9623                 /* referral level */
9624                 CHECK_BYTE_COUNT_TRANS(2);
9625                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9626                 COUNT_BYTES_TRANS(2);
9627
9628                 /* file name */
9629                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9630                 CHECK_STRING_TRANS(fn);
9631                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9632                         fn);
9633                 COUNT_BYTES_TRANS(fn_len);
9634
9635                 if (check_col(pinfo->cinfo, COL_INFO)) {
9636                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9637                             format_text(fn, strlen(fn)));
9638                 }
9639
9640                 break;
9641         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9642                 /* file name */
9643                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9644                 CHECK_STRING_TRANS(fn);
9645                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9646                         fn);
9647                 COUNT_BYTES_TRANS(fn_len);
9648
9649                 if (check_col(pinfo->cinfo, COL_INFO)) {
9650                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9651                             format_text(fn, strlen(fn)));
9652                 }
9653
9654                 break;
9655         }
9656
9657         /* ooops there were data we didnt know how to process */
9658         if(bc != 0){
9659                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
9660                 offset += bc;
9661         }
9662
9663         return offset;
9664 }
9665
9666 /*
9667  * XXX - just use "dissect_connect_flags()" here?
9668  */
9669 static guint16
9670 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9671 {
9672         guint16 mask;
9673         proto_item *item = NULL;
9674         proto_tree *tree = NULL;
9675
9676         mask = tvb_get_letohs(tvb, offset);
9677
9678         if(parent_tree){
9679                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9680                         "Flags: 0x%04x", mask);
9681                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9682         }
9683
9684         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9685                 tvb, offset, 2, mask);
9686         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9687                 tvb, offset, 2, mask);
9688
9689         return mask;
9690 }
9691
9692
9693 static int
9694 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9695 {
9696         guint16 mask;
9697         proto_item *item = NULL;
9698         proto_tree *tree = NULL;
9699
9700         mask = tvb_get_letohs(tvb, offset);
9701
9702         if(parent_tree){
9703                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9704                         "Flags: 0x%04x", mask);
9705                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9706         }
9707
9708         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9709                 tvb, offset, 2, mask);
9710         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9711                 tvb, offset, 2, mask);
9712
9713         offset += 2;
9714         return offset;
9715 }
9716
9717 static int
9718 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9719 {
9720         guint16 mask;
9721         proto_item *item = NULL;
9722         proto_tree *tree = NULL;
9723
9724         mask = tvb_get_letohs(tvb, offset);
9725
9726         if(parent_tree){
9727                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9728                         "Flags: 0x%04x", mask);
9729                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9730         }
9731
9732         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9733                 tvb, offset, 2, mask);
9734
9735         offset += 2;
9736
9737         return offset;
9738 }
9739
9740
9741 /* dfs inconsistency data  (4.4.2)
9742 */
9743 static int
9744 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9745     proto_tree *tree, int offset, guint16 *bcp)
9746 {
9747         smb_info_t *si = pinfo->private_data;
9748         int fn_len;
9749         const char *fn;
9750
9751         /*XXX shouldn this data hold version and size? unclear from doc*/
9752         /* referral version */
9753         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9754         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9755         COUNT_BYTES_TRANS_SUBR(2);
9756
9757         /* referral size */
9758         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9759         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9760         COUNT_BYTES_TRANS_SUBR(2);
9761
9762         /* referral server type */
9763         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9764         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9765         COUNT_BYTES_TRANS_SUBR(2);
9766
9767         /* referral flags */
9768         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9769         offset = dissect_dfs_referral_flags(tvb, tree, offset);
9770         *bcp -= 2;
9771
9772         /* node name */
9773         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9774         CHECK_STRING_TRANS_SUBR(fn);
9775         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9776                 fn);
9777         COUNT_BYTES_TRANS_SUBR(fn_len);
9778
9779         return offset;
9780 }
9781
9782 /* get dfs referral data  (4.4.1)
9783 */
9784 static int
9785 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9786     proto_tree *tree, int offset, guint16 *bcp)
9787 {
9788         smb_info_t *si = pinfo->private_data;
9789         guint16 numref;
9790         guint16 refsize;
9791         guint16 pathoffset;
9792         guint16 altpathoffset;
9793         guint16 nodeoffset;
9794         int fn_len;
9795         int stroffset;
9796         int offsetoffset;
9797         guint16 save_bc;
9798         const char *fn;
9799         int unklen;
9800         int ucstring_end;
9801         int ucstring_len;
9802
9803         /* path consumed */
9804         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9805         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9806         COUNT_BYTES_TRANS_SUBR(2);
9807
9808         /* num referrals */
9809         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9810         numref = tvb_get_letohs(tvb, offset);
9811         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9812         COUNT_BYTES_TRANS_SUBR(2);
9813
9814         /* get dfs flags */
9815         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9816         offset = dissect_get_dfs_flags(tvb, tree, offset);
9817         *bcp -= 2;
9818
9819         /* XXX - in at least one capture there appears to be 2 bytes
9820            of stuff after the Dfs flags, perhaps so that the header
9821            in front of the referral list is a multiple of 4 bytes long. */
9822         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9823         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9824         COUNT_BYTES_TRANS_SUBR(2);
9825
9826         /* if there are any referrals */
9827         if(numref){
9828                 proto_item *ref_item = NULL;
9829                 proto_tree *ref_tree = NULL;
9830                 int old_offset=offset;
9831
9832                 if(tree){
9833                         ref_item = proto_tree_add_text(tree,
9834                                 tvb, offset, *bcp, "Referrals");
9835                         ref_tree = proto_item_add_subtree(ref_item,
9836                                 ett_smb_dfs_referrals);
9837                 }
9838                 ucstring_end = -1;
9839
9840                 while(numref--){
9841                         proto_item *ri = NULL;
9842                         proto_tree *rt = NULL;
9843                         int old_offset=offset;
9844                         guint16 version;
9845
9846                         if(tree){
9847                                 ri = proto_tree_add_text(ref_tree,
9848                                         tvb, offset, *bcp, "Referral");
9849                                 rt = proto_item_add_subtree(ri,
9850                                         ett_smb_dfs_referral);
9851                         }
9852
9853                         /* referral version */
9854                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9855                         version = tvb_get_letohs(tvb, offset);
9856                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9857                                 tvb, offset, 2, version);
9858                         COUNT_BYTES_TRANS_SUBR(2);
9859
9860                         /* referral size */
9861                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9862                         refsize = tvb_get_letohs(tvb, offset);
9863                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9864                         COUNT_BYTES_TRANS_SUBR(2);
9865
9866                         /* referral server type */
9867                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9868                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9869                         COUNT_BYTES_TRANS_SUBR(2);
9870
9871                         /* referral flags */
9872                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9873                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
9874                         *bcp -= 2;
9875
9876                         switch(version){
9877
9878                         case 1:
9879                                 /* node name */
9880                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9881                                 CHECK_STRING_TRANS_SUBR(fn);
9882                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9883                                         fn);
9884                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9885                                 break;
9886
9887                         case 2:
9888                         case 3: /* XXX - like version 2, but not identical;
9889                                    seen in a capture, but the format isn't
9890                                    documented */
9891                                 /* proximity */
9892                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9893                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9894                                 COUNT_BYTES_TRANS_SUBR(2);
9895
9896                                 /* ttl */
9897                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9898                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9899                                 COUNT_BYTES_TRANS_SUBR(2);
9900
9901                                 /* path offset */
9902                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9903                                 pathoffset = tvb_get_letohs(tvb, offset);
9904                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9905                                 COUNT_BYTES_TRANS_SUBR(2);
9906
9907                                 /* alt path offset */
9908                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9909                                 altpathoffset = tvb_get_letohs(tvb, offset);
9910                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
9911                                 COUNT_BYTES_TRANS_SUBR(2);
9912
9913                                 /* node offset */
9914                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9915                                 nodeoffset = tvb_get_letohs(tvb, offset);
9916                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
9917                                 COUNT_BYTES_TRANS_SUBR(2);
9918
9919                                 /* path */
9920                                 if (pathoffset != 0) {
9921                                         stroffset = old_offset + pathoffset;
9922                                         offsetoffset = stroffset - offset;
9923                                         if (offsetoffset > 0 &&
9924                                             *bcp > offsetoffset) {
9925                                                 save_bc = *bcp;
9926                                                 *bcp -= offsetoffset;
9927                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9928                                                 CHECK_STRING_TRANS_SUBR(fn);
9929                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
9930                                                         fn);
9931                                                 stroffset += fn_len;
9932                                                 if (ucstring_end < stroffset)
9933                                                         ucstring_end = stroffset;
9934                                                 *bcp = save_bc;
9935                                         }
9936                                 }
9937
9938                                 /* alt path */
9939                                 if (altpathoffset != 0) {
9940                                         stroffset = old_offset + altpathoffset;
9941                                         offsetoffset = stroffset - offset;
9942                                         if (offsetoffset > 0 &&
9943                                             *bcp > offsetoffset) {
9944                                                 save_bc = *bcp;
9945                                                 *bcp -= offsetoffset;
9946                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9947                                                 CHECK_STRING_TRANS_SUBR(fn);
9948                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
9949                                                         fn);
9950                                                 stroffset += fn_len;
9951                                                 if (ucstring_end < stroffset)
9952                                                         ucstring_end = stroffset;
9953                                                 *bcp = save_bc;
9954                                         }
9955                                 }
9956
9957                                 /* node */
9958                                 if (nodeoffset != 0) {
9959                                         stroffset = old_offset + nodeoffset;
9960                                         offsetoffset = stroffset - offset;
9961                                         if (offsetoffset > 0 &&
9962                                             *bcp > offsetoffset) {
9963                                                 save_bc = *bcp;
9964                                                 *bcp -= offsetoffset;
9965                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9966                                                 CHECK_STRING_TRANS_SUBR(fn);
9967                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
9968                                                         fn);
9969                                                 stroffset += fn_len;
9970                                                 if (ucstring_end < stroffset)
9971                                                         ucstring_end = stroffset;
9972                                                 *bcp = save_bc;
9973                                         }
9974                                 }
9975                                 break;
9976                         }
9977
9978                         /*
9979                          * Show anything beyond the length of the referral
9980                          * as unknown data.
9981                          */
9982                         unklen = (old_offset + refsize) - offset;
9983                         if (unklen < 0) {
9984                                 /*
9985                                  * XXX - the length is bogus.
9986                                  */
9987                                 unklen = 0;
9988                         }
9989                         if (unklen != 0) {
9990                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
9991                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
9992                                     offset, unklen, TRUE);
9993                                 COUNT_BYTES_TRANS_SUBR(unklen);
9994                         }
9995
9996                         proto_item_set_len(ri, offset-old_offset);
9997                 }
9998
9999                 /*
10000                  * Treat the offset past the end of the last Unicode
10001                  * string after the referrals (if any) as the last
10002                  * offset.
10003                  */
10004                 if (ucstring_end > offset) {
10005                         ucstring_len = ucstring_end - offset;
10006                         if (*bcp < ucstring_len)
10007                                 ucstring_len = *bcp;
10008                         offset += ucstring_len;
10009                         *bcp -= ucstring_len;
10010                 }
10011                 proto_item_set_len(ref_item, offset-old_offset);
10012         }
10013
10014         return offset;
10015 }
10016
10017
10018 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10019    as described in 4.2.16.1
10020 */
10021 static int
10022 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10023     int offset, guint16 *bcp, gboolean *trunc)
10024 {
10025         /* create time */
10026         CHECK_BYTE_COUNT_SUBR(4);
10027         offset = dissect_smb_datetime(tvb, tree, offset,
10028                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10029                 FALSE);
10030         *bcp -= 4;
10031
10032         /* access time */
10033         CHECK_BYTE_COUNT_SUBR(4);
10034         offset = dissect_smb_datetime(tvb, tree, offset,
10035                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10036                 FALSE);
10037         *bcp -= 4;
10038
10039         /* last write time */
10040         CHECK_BYTE_COUNT_SUBR(4);
10041         offset = dissect_smb_datetime(tvb, tree, offset,
10042                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10043                 FALSE);
10044         *bcp -= 4;
10045
10046         /* data size */
10047         CHECK_BYTE_COUNT_SUBR(4);
10048         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10049         COUNT_BYTES_SUBR(4);
10050
10051         /* allocation size */
10052         CHECK_BYTE_COUNT_SUBR(4);
10053         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10054         COUNT_BYTES_SUBR(4);
10055
10056         /* File Attributes */
10057         CHECK_BYTE_COUNT_SUBR(2);
10058         offset = dissect_file_attributes(tvb, tree, offset, 2);
10059         *bcp -= 2;
10060
10061         /* ea length */
10062         CHECK_BYTE_COUNT_SUBR(4);
10063         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10064         COUNT_BYTES_SUBR(4);
10065
10066         *trunc = FALSE;
10067         return offset;
10068 }
10069
10070 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10071    as described in 4.2.16.2
10072 */
10073 static int
10074 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10075     int offset, guint16 *bcp, gboolean *trunc)
10076 {
10077         guint8 name_len;
10078         guint16 data_len;
10079         /* EA size */
10080
10081         CHECK_BYTE_COUNT_SUBR(4);
10082         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10083         COUNT_BYTES_SUBR(4);
10084
10085         while (*bcp > 0) {
10086                 proto_item *item;
10087                 proto_tree *subtree;
10088                 int start_offset = offset;
10089                 guint8 *name;
10090
10091                 item = proto_tree_add_text(
10092                         tree, tvb, offset, 0, "Extended Attribute");
10093                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10094
10095                 /* EA flags */
10096                 
10097                 CHECK_BYTE_COUNT_SUBR(1);
10098                 proto_tree_add_item(
10099                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10100                 COUNT_BYTES_SUBR(1);
10101
10102                 /* EA name length */
10103                 
10104                 name_len = tvb_get_guint8(tvb, offset);
10105
10106                 CHECK_BYTE_COUNT_SUBR(1);
10107                 proto_tree_add_item(
10108                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10109                 COUNT_BYTES_SUBR(1);
10110
10111                 /* EA data length */
10112
10113                 data_len = tvb_get_letohs(tvb, offset);
10114                 
10115                 CHECK_BYTE_COUNT_SUBR(2);
10116                 proto_tree_add_item(
10117                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10118                 COUNT_BYTES_SUBR(2);
10119
10120                 /* EA name */
10121
10122                 name = tvb_get_string(tvb, offset, name_len);
10123                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
10124                 g_free(name);
10125
10126                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10127                 proto_tree_add_item(
10128                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10129                         TRUE);
10130                 COUNT_BYTES_SUBR(name_len + 1);
10131
10132                 /* EA data */
10133                 
10134                 CHECK_BYTE_COUNT_SUBR(data_len);
10135                 proto_tree_add_item(
10136                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10137                 COUNT_BYTES_SUBR(data_len);
10138
10139                 proto_item_set_len(item, offset - start_offset);
10140         }
10141
10142         *trunc = FALSE;
10143         return offset;
10144 }
10145
10146 /* this dissects the SMB_INFO_IS_NAME_VALID
10147    as described in 4.2.16.3
10148 */
10149 static int
10150 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10151     int offset, guint16 *bcp, gboolean *trunc)
10152 {
10153         smb_info_t *si = pinfo->private_data;
10154         int fn_len;
10155         const char *fn;
10156
10157         /* file name */
10158         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10159         CHECK_STRING_SUBR(fn);
10160         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10161                 fn);
10162         COUNT_BYTES_SUBR(fn_len);
10163
10164         *trunc = FALSE;
10165         return offset;
10166 }
10167
10168 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10169    as described in 4.2.16.4
10170 */
10171 static int
10172 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10173     int offset, guint16 *bcp, gboolean *trunc)
10174 {
10175         /* create time */
10176         CHECK_BYTE_COUNT_SUBR(8);
10177         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
10178         *bcp -= 8;
10179
10180         /* access time */
10181         CHECK_BYTE_COUNT_SUBR(8);
10182         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
10183         *bcp -= 8;
10184
10185         /* last write time */
10186         CHECK_BYTE_COUNT_SUBR(8);
10187         offset = dissect_nt_64bit_time(tvb, tree, offset,
10188                 hf_smb_last_write_time);
10189         *bcp -= 8;
10190
10191         /* last change time */
10192         CHECK_BYTE_COUNT_SUBR(8);
10193         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
10194         *bcp -= 8;
10195
10196         /* File Attributes */
10197         CHECK_BYTE_COUNT_SUBR(4);
10198         offset = dissect_file_attributes(tvb, tree, offset, 4);
10199         *bcp -= 4;
10200
10201         *trunc = FALSE;
10202         return offset;
10203 }
10204
10205 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10206    as described in 4.2.16.5
10207 */
10208 static int
10209 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10210     int offset, guint16 *bcp, gboolean *trunc)
10211 {
10212         /* allocation size */
10213         CHECK_BYTE_COUNT_SUBR(8);
10214         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10215         COUNT_BYTES_SUBR(8);
10216
10217         /* end of file */
10218         CHECK_BYTE_COUNT_SUBR(8);
10219         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10220         COUNT_BYTES_SUBR(8);
10221
10222         /* number of links */
10223         CHECK_BYTE_COUNT_SUBR(4);
10224         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10225         COUNT_BYTES_SUBR(4);
10226
10227         /* delete pending */
10228         CHECK_BYTE_COUNT_SUBR(1);
10229         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
10230         COUNT_BYTES_SUBR(1);
10231
10232         /* is directory */
10233         CHECK_BYTE_COUNT_SUBR(1);
10234         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10235         COUNT_BYTES_SUBR(1);
10236
10237         *trunc = FALSE;
10238         return offset;
10239 }
10240
10241 /* this dissects the SMB_QUERY_FILE_EA_INFO
10242    as described in 4.2.16.6
10243 */
10244 static int
10245 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10246     int offset, guint16 *bcp, gboolean *trunc)
10247 {
10248         /* ea length */
10249         CHECK_BYTE_COUNT_SUBR(4);
10250         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10251         COUNT_BYTES_SUBR(4);
10252
10253         *trunc = FALSE;
10254         return offset;
10255 }
10256
10257 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10258    as described in 4.2.16.7
10259    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10260    as described in 4.2.16.9
10261 */
10262 static int
10263 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10264     int offset, guint16 *bcp, gboolean *trunc)
10265 {
10266         smb_info_t *si = pinfo->private_data;
10267         int fn_len;
10268         const char *fn;
10269
10270         /* file name len */
10271         CHECK_BYTE_COUNT_SUBR(4);
10272         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10273         COUNT_BYTES_SUBR(4);
10274
10275         /* file name */
10276         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10277         CHECK_STRING_SUBR(fn);
10278         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10279                 fn);
10280         COUNT_BYTES_SUBR(fn_len);
10281
10282         *trunc = FALSE;
10283         return offset;
10284 }
10285
10286 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10287    as described in 4.2.16.8
10288 */
10289 static int
10290 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10291     int offset, guint16 *bcp, gboolean *trunc)
10292 {
10293
10294         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
10295         if (*trunc) {
10296                 return offset;
10297         }
10298         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
10299         if (*trunc) {
10300                 return offset;
10301         }
10302
10303         /* index number */
10304         CHECK_BYTE_COUNT_SUBR(8);
10305         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10306         COUNT_BYTES_SUBR(8);
10307
10308         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10309         if (*trunc)
10310                 return offset;
10311
10312         /* access flags */
10313         CHECK_BYTE_COUNT_SUBR(4);
10314         offset = dissect_smb_access_mask(tvb, tree, offset);
10315         COUNT_BYTES_SUBR(4);
10316
10317         /* index number */
10318         CHECK_BYTE_COUNT_SUBR(8);
10319         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10320         COUNT_BYTES_SUBR(8);
10321
10322         /* current offset */
10323         CHECK_BYTE_COUNT_SUBR(8);
10324         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10325         COUNT_BYTES_SUBR(8);
10326
10327         /* mode */
10328         CHECK_BYTE_COUNT_SUBR(4);
10329         offset = dissect_nt_create_options(tvb, tree, offset);
10330         *bcp -= 4;
10331
10332         /* alignment */
10333         CHECK_BYTE_COUNT_SUBR(4);
10334         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10335         COUNT_BYTES_SUBR(4);
10336
10337         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10338
10339         return offset;
10340 }
10341
10342 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10343    as described in 4.2.16.10
10344 */
10345 static int
10346 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10347     int offset, guint16 *bcp, gboolean *trunc)
10348 {
10349         proto_item *item;
10350         proto_tree *tree;
10351         int old_offset;
10352         guint32 neo;
10353         smb_info_t *si = pinfo->private_data;
10354         int fn_len;
10355         const char *fn;
10356         int padcnt;
10357
10358         for (;;) {
10359                 old_offset = offset;
10360
10361                 /* next entry offset */
10362                 CHECK_BYTE_COUNT_SUBR(4);
10363                 if(parent_tree){
10364                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10365                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10366                 } else {
10367                         item = NULL;
10368                         tree = NULL;
10369                 }
10370
10371                 neo = tvb_get_letohl(tvb, offset);
10372                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10373                 COUNT_BYTES_SUBR(4);
10374
10375                 /* stream name len */
10376                 CHECK_BYTE_COUNT_SUBR(4);
10377                 fn_len = tvb_get_letohl(tvb, offset);
10378                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10379                 COUNT_BYTES_SUBR(4);
10380
10381                 /* stream size */
10382                 CHECK_BYTE_COUNT_SUBR(8);
10383                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10384                 COUNT_BYTES_SUBR(8);
10385
10386                 /* allocation size */
10387                 CHECK_BYTE_COUNT_SUBR(8);
10388                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10389                 COUNT_BYTES_SUBR(8);
10390
10391                 /* stream name */
10392                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10393                 CHECK_STRING_SUBR(fn);
10394                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10395                         fn);
10396                 COUNT_BYTES_SUBR(fn_len);
10397
10398                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
10399                 proto_item_set_len(item, offset-old_offset);
10400
10401                 if (neo == 0)
10402                         break;  /* no more structures */
10403
10404                 /* skip to next structure */
10405                 padcnt = (old_offset + neo) - offset;
10406                 if (padcnt < 0) {
10407                         /*
10408                          * XXX - this is bogus; flag it?
10409                          */
10410                         padcnt = 0;
10411                 }
10412                 if (padcnt != 0) {
10413                         CHECK_BYTE_COUNT_SUBR(padcnt);
10414                         COUNT_BYTES_SUBR(padcnt);
10415                 }
10416         }
10417
10418         *trunc = FALSE;
10419         return offset;
10420 }
10421
10422 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10423    as described in 4.2.16.11
10424 */
10425 static int
10426 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10427     int offset, guint16 *bcp, gboolean *trunc)
10428 {
10429         /* compressed file size */
10430         CHECK_BYTE_COUNT_SUBR(8);
10431         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10432         COUNT_BYTES_SUBR(8);
10433
10434         /* compression format */
10435         CHECK_BYTE_COUNT_SUBR(2);
10436         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10437         COUNT_BYTES_SUBR(2);
10438
10439         /* compression unit shift */
10440         CHECK_BYTE_COUNT_SUBR(1);
10441         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10442         COUNT_BYTES_SUBR(1);
10443
10444         /* compression chunk shift */
10445         CHECK_BYTE_COUNT_SUBR(1);
10446         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10447         COUNT_BYTES_SUBR(1);
10448
10449         /* compression cluster shift */
10450         CHECK_BYTE_COUNT_SUBR(1);
10451         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10452         COUNT_BYTES_SUBR(1);
10453
10454         /* 3 reserved bytes */
10455         CHECK_BYTE_COUNT_SUBR(3);
10456         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10457         COUNT_BYTES_SUBR(3);
10458
10459         *trunc = FALSE;
10460         return offset;
10461 }
10462
10463 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
10464
10465 static const value_string unix_file_type_vals[] = {
10466         { 0, "File" },
10467         { 1, "Directory" },
10468         { 2, "Symbolic link" },
10469         { 3, "Character device" },
10470         { 4, "Block device" },
10471         { 5, "FIFO" },
10472         { 6, "Socket" },
10473         { 0, NULL }
10474 };
10475
10476 static int
10477 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10478                   int offset, guint16 *bcp, gboolean *trunc)
10479 {
10480         /* End of file (file size) */
10481         CHECK_BYTE_COUNT_SUBR(8);
10482         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
10483         COUNT_BYTES_SUBR(8);
10484
10485         /* Number of bytes */
10486         CHECK_BYTE_COUNT_SUBR(8);
10487         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
10488         COUNT_BYTES_SUBR(8);
10489
10490         /* Last status change */
10491         CHECK_BYTE_COUNT_SUBR(8);
10492         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
10493         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
10494
10495         /* Last access time */
10496         CHECK_BYTE_COUNT_SUBR(8);
10497         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
10498         *bcp -= 8;
10499
10500         /* Last modification time */
10501         CHECK_BYTE_COUNT_SUBR(8);
10502         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
10503         *bcp -= 8;
10504
10505         /* File owner uid */
10506         CHECK_BYTE_COUNT_SUBR(8);
10507         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
10508         COUNT_BYTES_SUBR(8);
10509
10510         /* File group gid */
10511         CHECK_BYTE_COUNT_SUBR(8);
10512         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
10513         COUNT_BYTES_SUBR(8);
10514
10515         /* File type */
10516         CHECK_BYTE_COUNT_SUBR(4);
10517         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
10518         COUNT_BYTES_SUBR(4);
10519
10520         /* Major device number */
10521         CHECK_BYTE_COUNT_SUBR(8);
10522         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
10523         COUNT_BYTES_SUBR(8);
10524
10525         /* Minor device number */
10526         CHECK_BYTE_COUNT_SUBR(8);
10527         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
10528         COUNT_BYTES_SUBR(8);
10529
10530         /* Unique id */
10531         CHECK_BYTE_COUNT_SUBR(8);
10532         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
10533         COUNT_BYTES_SUBR(8);
10534
10535         /* Permissions */
10536         CHECK_BYTE_COUNT_SUBR(8);
10537         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
10538         COUNT_BYTES_SUBR(8);
10539
10540         /* Nlinks */
10541         CHECK_BYTE_COUNT_SUBR(8);
10542         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
10543         COUNT_BYTES_SUBR(8);
10544
10545         /* Sometimes there is one extra byte in the data field which I
10546            guess could be padding, but we are only using 4 or 8 byte
10547            data types so this is a bit confusing. -tpot */
10548
10549         *trunc = FALSE;
10550         return offset;
10551 }
10552
10553 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
10554
10555 static int
10556 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10557                   int offset, guint16 *bcp, gboolean *trunc)
10558 {
10559         smb_info_t *si = pinfo->private_data;
10560         const char *fn;
10561         int fn_len;
10562
10563         /* Link destination */
10564
10565         fn = get_unicode_or_ascii_string(
10566                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10567
10568         CHECK_STRING_SUBR(fn);
10569         proto_tree_add_string(
10570                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
10571         COUNT_BYTES_SUBR(fn_len);
10572
10573         *trunc = FALSE;
10574         return offset;
10575 }
10576
10577 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
10578    as described in 4.2.19.2
10579 */
10580 static int
10581 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10582     int offset, guint16 *bcp, gboolean *trunc)
10583 {
10584         /* marked for deletion? */
10585         CHECK_BYTE_COUNT_SUBR(1);
10586         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
10587         COUNT_BYTES_SUBR(1);
10588
10589         *trunc = FALSE;
10590         return offset;
10591 }
10592
10593 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
10594    as described in 4.2.19.3
10595 */
10596 static int
10597 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10598     int offset, guint16 *bcp, gboolean *trunc)
10599 {
10600         /* file allocation size */
10601         CHECK_BYTE_COUNT_SUBR(8);
10602         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10603         COUNT_BYTES_SUBR(8);
10604
10605         *trunc = FALSE;
10606         return offset;
10607 }
10608
10609 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
10610    as described in 4.2.19.4
10611 */
10612 static int
10613 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10614     int offset, guint16 *bcp, gboolean *trunc)
10615 {
10616         /* file end of file offset */
10617         CHECK_BYTE_COUNT_SUBR(8);
10618         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10619         COUNT_BYTES_SUBR(8);
10620
10621         *trunc = FALSE;
10622         return offset;
10623 }
10624
10625 /* Set File Rename Info */
10626
10627 static const true_false_string tfs_smb_replace = {
10628         "Remove target file if it exists",
10629         "Do NOT remove target file if it exists",
10630 };
10631
10632 static int
10633 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10634                     int offset, guint16 *bcp, gboolean *trunc)
10635 {
10636         smb_info_t *si = pinfo->private_data;
10637         const char *fn;
10638         guint32 target_name_len;
10639         int fn_len;
10640
10641         /* Replace flag */
10642         CHECK_BYTE_COUNT_SUBR(4);
10643         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
10644         COUNT_BYTES_SUBR(4);
10645
10646         /* Root directory handle */
10647         CHECK_BYTE_COUNT_SUBR(4);
10648         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
10649         COUNT_BYTES_SUBR(4);
10650
10651         /* Target name length */
10652         CHECK_BYTE_COUNT_SUBR(4);
10653         target_name_len = tvb_get_letohl(tvb, offset);
10654         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
10655         COUNT_BYTES_SUBR(4);
10656
10657         /* Target name */
10658         fn_len = target_name_len;
10659         fn = get_unicode_or_ascii_string(
10660                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10661
10662         CHECK_STRING_SUBR(fn);
10663         proto_tree_add_string(
10664                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
10665         COUNT_BYTES_SUBR(fn_len);
10666
10667         *trunc = FALSE;
10668         return offset;
10669 }
10670
10671 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
10672   TRANS2_QUERY_FILE_INFORMATION*/
10673 static int
10674 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10675     int offset, guint16 *bcp)
10676 {
10677         smb_info_t *si;
10678         gboolean trunc;
10679
10680         if(!*bcp){
10681                 return offset;
10682         }
10683
10684         si = (smb_info_t *)pinfo->private_data;
10685         switch(si->info_level){
10686         case 1:         /*Info Standard*/
10687                 
10688         case 2:         /*Info Query EA Size*/
10689                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
10690                     &trunc);
10691                 break;
10692         case 3:         /*Info Query EAs From List*/
10693         case 4:         /*Info Query All EAs*/
10694                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
10695                     &trunc);
10696                 break;
10697         case 6:         /*Info Is Name Valid*/
10698                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
10699                     &trunc);
10700                 break;
10701         case 0x0101:    /*Query File Basic Info*/
10702         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10703                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
10704                     &trunc);
10705                 break;
10706         case 0x0102:    /*Query File Standard Info*/
10707         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
10708                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
10709                     &trunc);
10710                 break;
10711         case 0x0103:    /*Query File EA Info*/
10712         case 1007:      /* SMB_FILE_EA_INFORMATION */
10713                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
10714                     &trunc);
10715                 break;
10716         case 0x0104:    /*Query File Name Info*/
10717         case 1009:      /* SMB_FILE_NAME_INFORMATION */
10718                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
10719                     &trunc);
10720                 break;
10721         case 0x0107:    /*Query File All Info*/
10722         case 1018:      /* SMB_FILE_ALL_INFORMATION */
10723                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
10724                     &trunc);
10725                 break;
10726         case 0x0108:    /*Query File Alt File Info*/
10727         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
10728                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
10729                     &trunc);
10730                 break;
10731         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
10732                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
10733         case 0x0109:    /*Query File Stream Info*/
10734                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
10735                     &trunc);
10736                 break;
10737         case 0x010b:    /*Query File Compression Info*/
10738         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
10739                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
10740                     &trunc);
10741                 break;
10742         case 0x0200:    /* Query File Unix Basic*/
10743                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
10744                                            &trunc);
10745                 break;
10746         case 0x0201:    /* Query File Unix Link*/
10747                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
10748                                            &trunc);
10749                 break;
10750         case 0x0202:    /* Query File Unix HardLink*/
10751                 /* XXX add this from the SNIA doc */
10752                 break;
10753         }
10754
10755         return offset;
10756 }
10757
10758 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
10759   TRANS2_SET_FILE_INFORMATION*/
10760 static int
10761 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10762     int offset, guint16 *bcp)
10763 {
10764         smb_info_t *si;
10765         gboolean trunc;
10766
10767         if(!*bcp){
10768                 return offset;
10769         }
10770
10771         si = (smb_info_t *)pinfo->private_data;
10772         switch(si->info_level){
10773         case 1:         /*Info Standard*/
10774                 
10775         case 2:         /*Info Query EA Size*/
10776                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
10777                     &trunc);
10778                 break;
10779         case 4:         /*Info Query All EAs*/
10780                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
10781                     &trunc);
10782                 break;
10783         case 0x0101:    /*Set File Basic Info*/
10784         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10785                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
10786                     &trunc);
10787                 break;
10788         case 0x0102:    /*Set File Disposition Info*/
10789                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
10790                     &trunc);
10791                 break;
10792         case 0x0103:    /*Set File Allocation Info*/
10793                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
10794                     &trunc);
10795                 break;
10796         case 0x0104:    /*Set End Of File Info*/
10797                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
10798                     &trunc);
10799                 break;
10800         case 0x0200:    /*Set File Unix Basic.  Same as query. */
10801                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
10802                     &trunc);
10803                 break;
10804         case 0x0201:    /*Set File Unix Link.  Same as query. */
10805                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
10806                     &trunc);
10807                 break;
10808         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
10809                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
10810                     &trunc);
10811                 break;
10812         case 1010:      /* Set File Rename */
10813                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
10814                     &trunc);
10815                 break;
10816         case 1013:
10817         case 1014:
10818         case 1016:
10819         case 1019:
10820         case 1020:
10821         case 1023:
10822         case 1025:
10823         case 1029:
10824         case 1032:
10825         case 1039:
10826         case 1040:
10827                 /* XXX: TODO, extra levels discovered by tridge */
10828                 break;
10829         }
10830
10831         return offset;
10832 }
10833
10834
10835 static const true_false_string tfs_quota_flags_deny_disk = {
10836         "DENY DISK SPACE for users exceeding quota limit",
10837         "Do NOT deny disk space for users exceeding quota limit"
10838 };
10839 static const true_false_string tfs_quota_flags_log_limit = {
10840         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10841         "Do NOT log event when a user exceeds their quota limit"
10842 };
10843 static const true_false_string tfs_quota_flags_log_warning = {
10844         "LOG EVENT when a user exceeds their WARNING LEVEL",
10845         "Do NOT log event when a user exceeds their warning level"
10846 };
10847 static const true_false_string tfs_quota_flags_enabled = {
10848         "Quotas are ENABLED of this fs",
10849         "Quotas are NOT enabled on this fs"
10850 };
10851 static void
10852 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10853 {
10854         guint8 mask;
10855         proto_item *item = NULL;
10856         proto_tree *tree = NULL;
10857
10858         mask = tvb_get_guint8(tvb, offset);
10859
10860         if(parent_tree){
10861                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10862                         "Quota Flags: 0x%02x %s", mask,
10863                         mask?"Enabled":"Disabled");
10864                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10865         }
10866
10867         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10868                 tvb, offset, 1, mask);
10869         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10870                 tvb, offset, 1, mask);
10871         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10872                 tvb, offset, 1, mask);
10873
10874         if(mask && (!(mask&0x01))){
10875                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10876                         tvb, offset, 1, 0x01);
10877         } else {
10878                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10879                         tvb, offset, 1, mask);
10880         }
10881
10882 }
10883
10884 static int
10885 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
10886 {
10887         /* first 24 bytes are unknown */
10888         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10889         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10890                     offset, 24, TRUE);
10891         COUNT_BYTES_TRANS_SUBR(24);
10892
10893         /* number of bytes for quota warning */
10894         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10895         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10896         COUNT_BYTES_TRANS_SUBR(8);
10897
10898         /* number of bytes for quota limit */
10899         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10900         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10901         COUNT_BYTES_TRANS_SUBR(8);
10902
10903         /* one byte of quota flags */
10904         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10905         dissect_quota_flags(tvb, tree, offset);
10906         COUNT_BYTES_TRANS_SUBR(1);
10907
10908         /* these 7 bytes are unknown */
10909         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10910         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10911                     offset, 7, TRUE);
10912         COUNT_BYTES_TRANS_SUBR(7);
10913
10914         return offset;
10915 }
10916
10917 static int
10918 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10919     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10920 {
10921         proto_item *item = NULL;
10922         proto_tree *tree = NULL;
10923         smb_info_t *si;
10924
10925         si = (smb_info_t *)pinfo->private_data;
10926
10927         if(parent_tree){
10928                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10929                                 "%s Data",
10930                                 val_to_str(subcmd, trans2_cmd_vals,
10931                                                 "Unknown (0x%02x)"));
10932                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10933         }
10934
10935         switch(subcmd){
10936         case 0x00:      /*TRANS2_OPEN2*/
10937                 /* XXX dont know how to decode FEAList */
10938                 break;
10939         case 0x01:      /*TRANS2_FIND_FIRST2*/
10940                 /* XXX dont know how to decode FEAList */
10941                 break;
10942         case 0x02:      /*TRANS2_FIND_NEXT2*/
10943                 /* XXX dont know how to decode FEAList */
10944                 break;
10945         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10946                 /* no data field in this request */
10947                 break;
10948         case 0x04:      /* TRANS2_SET_QUOTA */
10949                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
10950                 break;
10951         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10952                 /* no data field in this request */
10953                 /*
10954                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10955                  * Extensions Version 3.0, Document Version 1.11,
10956                  * July 19, 1990" says there may be "Additional
10957                  * FileInfoLevel dependent information" here.
10958                  *
10959                  * Was that just a cut-and-pasteo?
10960                  * TRANS2_SET_PATH_INFORMATION *does* have that information
10961                  * here.
10962                  */
10963                 break;
10964         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10965                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
10966                 break;
10967         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10968                 /* no data field in this request */
10969                 /*
10970                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10971                  * Extensions Version 3.0, Document Version 1.11,
10972                  * July 19, 1990" says there may be "Additional
10973                  * FileInfoLevel dependent information" here.
10974                  *
10975                  * Was that just a cut-and-pasteo?
10976                  * TRANS2_SET_FILE_INFORMATION *does* have that information
10977                  * here.
10978                  */
10979                 break;
10980         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10981                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
10982                 break;
10983         case 0x09:      /*TRANS2_FSCTL*/
10984                 /*XXX dont know how to decode this yet */
10985
10986                 /*
10987                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10988                  * Extensions Version 3.0, Document Version 1.11,
10989                  * July 19, 1990" says this this contains a
10990                  * "File system specific data block".  (That means we
10991                  * may not be able to dissect it in any case.)
10992                  */
10993                 break;
10994         case 0x0a:      /*TRANS2_IOCTL2*/
10995                 /*XXX dont know how to decode this yet */
10996
10997                 /*
10998                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10999                  * Extensions Version 3.0, Document Version 1.11,
11000                  * July 19, 1990" says this this contains a
11001                  * "Device/function specific data block".  (That
11002                  * means we may not be able to dissect it in any case.)
11003                  */
11004                 break;
11005         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11006                 /*XXX dont know how to decode this yet */
11007
11008                 /*
11009                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11010                  * Extensions Version 3.0, Document Version 1.11,
11011                  * July 19, 1990" says this this contains "additional
11012                  * level dependent match data".
11013                  */
11014                 break;
11015         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11016                 /*XXX dont know how to decode this yet */
11017
11018                 /*
11019                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11020                  * Extensions Version 3.0, Document Version 1.11,
11021                  * July 19, 1990" says this this contains "additional
11022                  * level dependent monitor information".
11023                  */
11024                 break;
11025         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11026                 /* XXX optional FEAList, unknown what FEAList looks like*/
11027                 break;
11028         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11029                 /*XXX dont know how to decode this yet */
11030                 break;
11031         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11032                 /* no data field in this request */
11033                 break;
11034         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11035                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11036                 break;
11037         }
11038
11039         /* ooops there were data we didnt know how to process */
11040         if(dc != 0){
11041                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11042                 offset += dc;
11043         }
11044
11045         return offset;
11046 }
11047
11048
11049 static void
11050 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11051     proto_tree *tree)
11052 {
11053         int i;
11054         int offset;
11055         guint length;
11056
11057         /*
11058          * Show the setup words.
11059          */
11060         if (s_tvb != NULL) {
11061                 length = tvb_reported_length(s_tvb);
11062                 for (i = 0, offset = 0; length >= 2;
11063                     i++, offset += 2, length -= 2) {
11064                         /*
11065                          * XXX - add a setup word filterable field?
11066                          */
11067                         proto_tree_add_text(tree, s_tvb, offset, 2,
11068                             "Setup Word %d: 0x%04x", i,
11069                             tvb_get_letohs(s_tvb, offset));
11070                 }
11071         }
11072
11073         /*
11074          * Show the parameters, if any.
11075          */
11076         if (p_tvb != NULL) {
11077                 length = tvb_reported_length(p_tvb);
11078                 if (length != 0) {
11079                         proto_tree_add_text(tree, p_tvb, 0, length,
11080                             "Parameters: %s",
11081                             tvb_bytes_to_str(p_tvb, 0, length));
11082                 }
11083         }
11084
11085         /*
11086          * Show the data, if any.
11087          */
11088         if (d_tvb != NULL) {
11089                 length = tvb_reported_length(d_tvb);
11090                 if (length != 0) {
11091                         proto_tree_add_text(tree, d_tvb, 0, length,
11092                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11093                 }
11094         }
11095 }
11096
11097 /* This routine handles the following 4 calls
11098    Transaction  0x25
11099    Transaction Secondary 0x26
11100    Transaction2 0x32
11101    Transaction2 Secondary 0x33
11102 */
11103 static int
11104 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11105 {
11106         guint8 wc, sc=0;
11107         int so=offset;
11108         int sl=0;
11109         int spo=offset;
11110         int spc=0;
11111         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11112         int subcmd = -1;
11113         guint32 to;
11114         int an_len;
11115         const char *an = NULL;
11116         smb_info_t *si;
11117         smb_transact2_info_t *t2i;
11118         smb_transact_info_t *tri;
11119         guint16 bc;
11120         int padcnt;
11121         gboolean dissected_trans;
11122
11123         si = (smb_info_t *)pinfo->private_data;
11124
11125         WORD_COUNT;
11126
11127         if(wc==8){
11128                 /*secondary client request*/
11129
11130                 /* total param count, only a 16bit integer here*/
11131                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11132                 offset += 2;
11133
11134                 /* total data count , only 16bit integer here*/
11135                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11136                 offset += 2;
11137
11138                 /* param count */
11139                 pc = tvb_get_letohs(tvb, offset);
11140                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11141                 offset += 2;
11142
11143                 /* param offset */
11144                 po = tvb_get_letohs(tvb, offset);
11145                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11146                 offset += 2;
11147
11148                 /* param disp */
11149                 pd = tvb_get_letohs(tvb, offset);
11150                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11151                 offset += 2;
11152
11153                 /* data count */
11154                 dc = tvb_get_letohs(tvb, offset);
11155                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11156                 offset += 2;
11157
11158                 /* data offset */
11159                 od = tvb_get_letohs(tvb, offset);
11160                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11161                 offset += 2;
11162
11163                 /* data disp */
11164                 dd = tvb_get_letohs(tvb, offset);
11165                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11166                 offset += 2;
11167
11168                 if(si->cmd==SMB_COM_TRANSACTION2){
11169                         guint16 fid;
11170
11171                         /* fid */
11172                         fid = tvb_get_letohs(tvb, offset);
11173                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11174
11175                         offset += 2;
11176                 }
11177
11178                 /* There are no setup words. */
11179                 so = offset;
11180                 sc = 0;
11181                 sl = 0;
11182         } else {
11183                 /* it is not a secondary request */
11184
11185                 /* total param count , only a 16 bit integer here*/
11186                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11187                 offset += 2;
11188
11189                 /* total data count , only 16bit integer here*/
11190                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11191                 offset += 2;
11192
11193                 /* max param count , only 16bit integer here*/
11194                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11195                 offset += 2;
11196
11197                 /* max data count, only 16bit integer here*/
11198                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11199                 offset += 2;
11200
11201                 /* max setup count, only 16bit integer here*/
11202                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11203                 offset += 1;
11204
11205                 /* reserved byte */
11206                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11207                 offset += 1;
11208
11209                 /* transaction flags */
11210                 tf = dissect_transaction_flags(tvb, tree, offset);
11211                 offset += 2;
11212
11213                 /* timeout */
11214                 to = tvb_get_letohl(tvb, offset);
11215                 if (to == 0)
11216                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11217                 else if (to == 0xffffffff)
11218                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11219                 else
11220                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11221                 offset += 4;
11222
11223                 /* 2 reserved bytes */
11224                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11225                 offset += 2;
11226
11227                 /* param count */
11228                 pc = tvb_get_letohs(tvb, offset);
11229                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11230                 offset += 2;
11231
11232                 /* param offset */
11233                 po = tvb_get_letohs(tvb, offset);
11234                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11235                 offset += 2;
11236
11237                 /* param displacement is zero here */
11238                 pd = 0;
11239
11240                 /* data count */
11241                 dc = tvb_get_letohs(tvb, offset);
11242                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11243                 offset += 2;
11244
11245                 /* data offset */
11246                 od = tvb_get_letohs(tvb, offset);
11247                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11248                 offset += 2;
11249
11250                 /* data displacement is zero here */
11251                 dd = 0;
11252
11253                 /* setup count */
11254                 sc = tvb_get_guint8(tvb, offset);
11255                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11256                 offset += 1;
11257
11258                 /* reserved byte */
11259                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11260                 offset += 1;
11261
11262                 /* this is where the setup bytes, if any start */
11263                 so = offset;
11264                 sl = sc*2;
11265
11266                 /* if there were any setup bytes, decode them */
11267                 if(sc){
11268                         switch(si->cmd){
11269
11270                         case SMB_COM_TRANSACTION2:
11271                                 /* TRANSACTION2 only has one setup word and
11272                                    that is the subcommand code.
11273
11274                                    XXX - except for TRANS2_FSCTL
11275                                    and TRANS2_IOCTL. */
11276                                 subcmd = tvb_get_letohs(tvb, offset);
11277                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11278                                     tvb, offset, 2, subcmd);
11279                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11280                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11281                                             val_to_str(subcmd, trans2_cmd_vals,
11282                                                 "Unknown (0x%02x)"));
11283                                 }
11284                                 if (!si->unidir) {
11285                                         if(!pinfo->fd->flags.visited){
11286                                                 /*
11287                                                  * Allocate a new
11288                                                  * smb_transact2_info_t
11289                                                  * structure.
11290                                                  */
11291                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11292                                                 t2i->subcmd = subcmd;
11293                                                 t2i->info_level = -1;
11294                                                 t2i->resume_keys = FALSE;
11295                                                 si->sip->extra_info = t2i;
11296                                         }
11297                                 }
11298
11299                                 /*
11300                                  * XXX - process TRANS2_FSCTL and
11301                                  * TRANS2_IOCTL setup words here.
11302                                  */
11303                                 break;
11304
11305                         case SMB_COM_TRANSACTION:
11306                                 /* TRANSACTION setup words processed below */
11307                                 break;
11308                         }
11309
11310                         offset += sl;
11311                 }
11312         }
11313
11314         BYTE_COUNT;
11315
11316         if(wc!=8){
11317                 /* primary request */
11318                 /* name is NULL if transaction2 */
11319                 if(si->cmd == SMB_COM_TRANSACTION){
11320                         /* Transaction Name */
11321                         an = get_unicode_or_ascii_string(tvb, &offset,
11322                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11323                         if (an == NULL)
11324                                 goto endofcommand;
11325                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11326                                 offset, an_len, an);
11327                         COUNT_BYTES(an_len);
11328                 }
11329         }
11330
11331         /*
11332          * The pipe or mailslot arguments for Transaction start with
11333          * the first setup word (or where the first setup word would
11334          * be if there were any setup words), and run to the current
11335          * offset (which could mean that there aren't any).
11336          */
11337         spo = so;
11338         spc = offset - spo;
11339
11340         /* parameters */
11341         if(po>offset){
11342                 /* We have some initial padding bytes.
11343                 */
11344                 padcnt = po-offset;
11345                 if (padcnt > bc)
11346                         padcnt = bc;
11347                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11348                 COUNT_BYTES(padcnt);
11349         }
11350         if(pc){
11351                 CHECK_BYTE_COUNT(pc);
11352                 switch(si->cmd) {
11353
11354                 case SMB_COM_TRANSACTION2:
11355                         /* TRANSACTION2 parameters*/
11356                         offset = dissect_transaction2_request_parameters(tvb,
11357                             pinfo, tree, offset, subcmd, pc);
11358                         bc -= pc;
11359                         break;
11360
11361                 case SMB_COM_TRANSACTION:
11362                         /* TRANSACTION parameters processed below */
11363                         COUNT_BYTES(pc);
11364                         break;
11365                 }
11366         }
11367
11368         /* data */
11369         if(od>offset){
11370                 /* We have some initial padding bytes.
11371                 */
11372                 padcnt = od-offset;
11373                 if (padcnt > bc)
11374                         padcnt = bc;
11375                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11376                 COUNT_BYTES(padcnt);
11377         }
11378         if(dc){
11379                 CHECK_BYTE_COUNT(dc);
11380                 switch(si->cmd){
11381
11382                 case SMB_COM_TRANSACTION2:
11383                         /* TRANSACTION2 data*/
11384                         offset = dissect_transaction2_request_data(tvb, pinfo,
11385                             tree, offset, subcmd, dc);
11386                         bc -= dc;
11387                         break;
11388
11389                 case SMB_COM_TRANSACTION:
11390                         /* TRANSACTION data processed below */
11391                         COUNT_BYTES(dc);
11392                         break;
11393                 }
11394         }
11395
11396         /*TRANSACTION request parameters */
11397         if(si->cmd==SMB_COM_TRANSACTION){
11398                 /*XXX replace this block with a function and use that one
11399                      for both requests/responses*/
11400                 if(dd==0){
11401                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11402                         tvbuff_t *sp_tvb, *pd_tvb;
11403
11404                         if(pc>0){
11405                                 if(pc>tvb_length_remaining(tvb, po)){
11406                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11407                                 } else {
11408                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11409                                 }
11410                         } else {
11411                                 p_tvb = NULL;
11412                         }
11413                         if(dc>0){
11414                                 if(dc>tvb_length_remaining(tvb, od)){
11415                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11416                                 } else {
11417                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11418                                 }
11419                         } else {
11420                                 d_tvb = NULL;
11421                         }
11422                         if(sl){
11423                                 if(sl>tvb_length_remaining(tvb, so)){
11424                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11425                                 } else {
11426                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11427                                 }
11428                         } else {
11429                                 s_tvb = NULL;
11430                         }
11431
11432                         if (!si->unidir) {
11433                                 if(!pinfo->fd->flags.visited){
11434                                         /*
11435                                          * Allocate a new smb_transact_info_t
11436                                          * structure.
11437                                          */
11438                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11439                                         tri->subcmd = -1;
11440                                         tri->trans_subcmd = -1;
11441                                         tri->function = -1;
11442                                         tri->fid = -1;
11443                                         tri->lanman_cmd = 0;
11444                                         tri->param_descrip = NULL;
11445                                         tri->data_descrip = NULL;
11446                                         tri->aux_data_descrip = NULL;
11447                                         tri->info_level = -1;
11448                                         si->sip->extra_info = tri;
11449                                 } else {
11450                                         /*
11451                                          * We already filled the structure
11452                                          * in; don't bother doing so again.
11453                                          */
11454                                         tri = NULL;
11455                                 }
11456                         } else {
11457                                 /*
11458                                  * This is a unidirectional message, for
11459                                  * which there will be no reply; don't
11460                                  * bother allocating an "smb_transact_info_t"
11461                                  * structure for it.
11462                                  */
11463                                 tri = NULL;
11464                         }
11465                         dissected_trans = FALSE;
11466                         if(strncmp("\\PIPE\\", an, 6) == 0){
11467                                 if (tri != NULL)
11468                                         tri->subcmd=TRANSACTION_PIPE;
11469
11470                                 /*
11471                                  * A tvbuff containing the setup words and
11472                                  * the pipe path.
11473                                  */
11474                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11475
11476                                 /*
11477                                  * A tvbuff containing the parameters and the
11478                                  * data.
11479                                  */
11480                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11481
11482                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11483                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11484                                     top_tree);
11485
11486                                 /* In case we did not see the TreeConnect call,
11487                                    store this TID here as well as a IPC TID 
11488                                    so we know that future Read/Writes to this 
11489                                    TID is (probably) DCERPC.
11490                                 */
11491                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
11492                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
11493                                 }
11494                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
11495                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11496                                 if (tri != NULL)
11497                                         tri->subcmd=TRANSACTION_MAILSLOT;
11498
11499                                 /*
11500                                  * A tvbuff containing the setup words and
11501                                  * the mailslot path.
11502                                  */
11503                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11504                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11505                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11506                         }
11507                         if (!dissected_trans)
11508                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11509                 } else {
11510                         if(check_col(pinfo->cinfo, COL_INFO)){
11511                                 col_append_str(pinfo->cinfo, COL_INFO,
11512                                         "[transact continuation]");
11513                         }
11514                 }
11515         }
11516
11517         END_OF_SMB
11518
11519         return offset;
11520 }
11521
11522
11523
11524 static int
11525 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11526     int offset, guint16 *bcp, gboolean *trunc)
11527 {
11528         int fn_len;
11529         const char *fn;
11530         int old_offset = offset;
11531         proto_item *item = NULL;
11532         proto_tree *tree = NULL;
11533         smb_info_t *si;
11534         smb_transact2_info_t *t2i;
11535         gboolean resume_keys = FALSE;
11536
11537         si = (smb_info_t *)pinfo->private_data;
11538         if (si->sip != NULL) {
11539                 t2i = si->sip->extra_info;
11540                 if (t2i != NULL)
11541                         resume_keys = t2i->resume_keys;
11542         }
11543
11544         if(parent_tree){
11545                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11546                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11547                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11548         }
11549
11550         if (resume_keys) {
11551                 /* resume key */
11552                 CHECK_BYTE_COUNT_SUBR(4);
11553                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11554                 COUNT_BYTES_SUBR(4);
11555         }
11556
11557         /* create time */
11558         CHECK_BYTE_COUNT_SUBR(4);
11559         offset = dissect_smb_datetime(tvb, tree, offset,
11560                 hf_smb_create_time,
11561                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11562         *bcp -= 4;
11563
11564         /* access time */
11565         CHECK_BYTE_COUNT_SUBR(4);
11566         offset = dissect_smb_datetime(tvb, tree, offset,
11567                 hf_smb_access_time,
11568                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11569         *bcp -= 4;
11570
11571         /* last write time */
11572         CHECK_BYTE_COUNT_SUBR(4);
11573         offset = dissect_smb_datetime(tvb, tree, offset,
11574                 hf_smb_last_write_time,
11575                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11576         *bcp -= 4;
11577
11578         /* data size */
11579         CHECK_BYTE_COUNT_SUBR(4);
11580         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11581         COUNT_BYTES_SUBR(4);
11582
11583         /* allocation size */
11584         CHECK_BYTE_COUNT_SUBR(4);
11585         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11586         COUNT_BYTES_SUBR(4);
11587
11588         /* File Attributes */
11589         CHECK_BYTE_COUNT_SUBR(2);
11590         offset = dissect_file_attributes(tvb, tree, offset, 2);
11591         *bcp -= 2;
11592
11593         /* file name len */
11594         CHECK_BYTE_COUNT_SUBR(1);
11595         fn_len = tvb_get_guint8(tvb, offset);
11596         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11597         COUNT_BYTES_SUBR(1);
11598         if (si->unicode)
11599                 fn_len += 2;    /* include terminating '\0' */
11600         else
11601                 fn_len++;       /* include terminating '\0' */
11602
11603         /* file name */
11604         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11605         CHECK_STRING_SUBR(fn);
11606         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11607                 fn);
11608         COUNT_BYTES_SUBR(fn_len);
11609
11610         if (check_col(pinfo->cinfo, COL_INFO)) {
11611                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11612                     format_text(fn, strlen(fn)));
11613         }
11614
11615         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
11616         proto_item_set_len(item, offset-old_offset);
11617
11618         *trunc = FALSE;
11619         return offset;
11620 }
11621
11622 static int
11623 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11624     int offset, guint16 *bcp, gboolean *trunc)
11625 {
11626         int fn_len;
11627         const char *fn;
11628         int old_offset = offset;
11629         proto_item *item = NULL;
11630         proto_tree *tree = NULL;
11631         smb_info_t *si;
11632         smb_transact2_info_t *t2i;
11633         gboolean resume_keys = FALSE;
11634
11635         si = (smb_info_t *)pinfo->private_data;
11636         if (si->sip != NULL) {
11637                 t2i = si->sip->extra_info;
11638                 if (t2i != NULL)
11639                         resume_keys = t2i->resume_keys;
11640         }
11641
11642         if(parent_tree){
11643                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11644                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11645                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11646         }
11647
11648         if (resume_keys) {
11649                 /* resume key */
11650                 CHECK_BYTE_COUNT_SUBR(4);
11651                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11652                 COUNT_BYTES_SUBR(4);
11653         }
11654
11655         /* create time */
11656         CHECK_BYTE_COUNT_SUBR(4);
11657         offset = dissect_smb_datetime(tvb, tree, offset,
11658                 hf_smb_create_time,
11659                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11660         *bcp -= 4;
11661
11662         /* access time */
11663         CHECK_BYTE_COUNT_SUBR(4);
11664         offset = dissect_smb_datetime(tvb, tree, offset,
11665                 hf_smb_access_time,
11666                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11667         *bcp -= 4;
11668
11669         /* last write time */
11670         CHECK_BYTE_COUNT_SUBR(4);
11671         offset = dissect_smb_datetime(tvb, tree, offset,
11672                 hf_smb_last_write_time,
11673                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11674         *bcp -= 4;
11675
11676         /* data size */
11677         CHECK_BYTE_COUNT_SUBR(4);
11678         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11679         COUNT_BYTES_SUBR(4);
11680
11681         /* allocation size */
11682         CHECK_BYTE_COUNT_SUBR(4);
11683         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11684         COUNT_BYTES_SUBR(4);
11685
11686         /* File Attributes */
11687         CHECK_BYTE_COUNT_SUBR(2);
11688         offset = dissect_file_attributes(tvb, tree, offset, 2);
11689         *bcp -= 2;
11690
11691         /* ea length */
11692         CHECK_BYTE_COUNT_SUBR(4);
11693         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11694         COUNT_BYTES_SUBR(4);
11695
11696         /* file name len */
11697         CHECK_BYTE_COUNT_SUBR(1);
11698         fn_len = tvb_get_guint8(tvb, offset);
11699         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11700         COUNT_BYTES_SUBR(1);
11701         if (si->unicode)
11702                 fn_len += 2;    /* include terminating '\0' */
11703         else
11704                 fn_len++;       /* include terminating '\0' */
11705
11706         /* file name */
11707         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11708         CHECK_STRING_SUBR(fn);
11709         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11710                 fn);
11711         COUNT_BYTES_SUBR(fn_len);
11712
11713         if (check_col(pinfo->cinfo, COL_INFO)) {
11714                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11715                     format_text(fn, strlen(fn)));
11716         }
11717
11718         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
11719         proto_item_set_len(item, offset-old_offset);
11720
11721         *trunc = FALSE;
11722         return offset;
11723 }
11724
11725 static int
11726 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11727     int offset, guint16 *bcp, gboolean *trunc)
11728 {
11729         int fn_len;
11730         const char *fn;
11731         int old_offset = offset;
11732         proto_item *item = NULL;
11733         proto_tree *tree = NULL;
11734         smb_info_t *si;
11735         guint32 neo;
11736         int padcnt;
11737
11738         si = (smb_info_t *)pinfo->private_data;
11739
11740         if(parent_tree){
11741                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11742                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11743                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11744         }
11745
11746         /*
11747          * We assume that the presence of a next entry offset implies the
11748          * absence of a resume key, as appears to be the case for 4.3.4.6.
11749          */
11750
11751         /* next entry offset */
11752         CHECK_BYTE_COUNT_SUBR(4);
11753         neo = tvb_get_letohl(tvb, offset);
11754         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11755         COUNT_BYTES_SUBR(4);
11756
11757         /* file index */
11758         CHECK_BYTE_COUNT_SUBR(4);
11759         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11760         COUNT_BYTES_SUBR(4);
11761
11762         /* create time */
11763         CHECK_BYTE_COUNT_SUBR(8);
11764         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11765         *bcp -= 8;
11766
11767         /* access time */
11768         CHECK_BYTE_COUNT_SUBR(8);
11769         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11770         *bcp -= 8;
11771
11772         /* last write time */
11773         CHECK_BYTE_COUNT_SUBR(8);
11774         offset = dissect_nt_64bit_time(tvb, tree, offset,
11775                 hf_smb_last_write_time);
11776         *bcp -= 8;
11777
11778         /* last change time */
11779         CHECK_BYTE_COUNT_SUBR(8);
11780         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11781         *bcp -= 8;
11782
11783         /* end of file */
11784         CHECK_BYTE_COUNT_SUBR(8);
11785         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11786         COUNT_BYTES_SUBR(8);
11787
11788         /* allocation size */
11789         CHECK_BYTE_COUNT_SUBR(8);
11790         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11791         COUNT_BYTES_SUBR(8);
11792
11793         /* Extended File Attributes */
11794         CHECK_BYTE_COUNT_SUBR(4);
11795         offset = dissect_file_ext_attr(tvb, tree, offset);
11796         *bcp -= 4;
11797
11798         /* file name len */
11799         CHECK_BYTE_COUNT_SUBR(4);
11800         fn_len = tvb_get_letohl(tvb, offset);
11801         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11802         COUNT_BYTES_SUBR(4);
11803
11804         /* file name */
11805         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11806         CHECK_STRING_SUBR(fn);
11807         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11808                 fn);
11809         COUNT_BYTES_SUBR(fn_len);
11810
11811         if (check_col(pinfo->cinfo, COL_INFO)) {
11812                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11813                     format_text(fn, strlen(fn)));
11814         }
11815
11816         /* skip to next structure */
11817         if(neo){
11818                 padcnt = (old_offset + neo) - offset;
11819                 if (padcnt < 0) {
11820                         /*
11821                          * XXX - this is bogus; flag it?
11822                          */
11823                         padcnt = 0;
11824                 }
11825                 if (padcnt != 0) {
11826                         CHECK_BYTE_COUNT_SUBR(padcnt);
11827                         COUNT_BYTES_SUBR(padcnt);
11828                 }
11829         }
11830
11831         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
11832         proto_item_set_len(item, offset-old_offset);
11833
11834         *trunc = FALSE;
11835         return offset;
11836 }
11837
11838 static int
11839 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11840     int offset, guint16 *bcp, gboolean *trunc)
11841 {
11842         int fn_len;
11843         const char *fn;
11844         int old_offset = offset;
11845         proto_item *item = NULL;
11846         proto_tree *tree = NULL;
11847         smb_info_t *si;
11848         guint32 neo;
11849         int padcnt;
11850
11851         si = (smb_info_t *)pinfo->private_data;
11852
11853         if(parent_tree){
11854                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11855                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11856                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11857         }
11858
11859         /*
11860          * We assume that the presence of a next entry offset implies the
11861          * absence of a resume key, as appears to be the case for 4.3.4.6.
11862          */
11863
11864         /* next entry offset */
11865         CHECK_BYTE_COUNT_SUBR(4);
11866         neo = tvb_get_letohl(tvb, offset);
11867         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11868         COUNT_BYTES_SUBR(4);
11869
11870         /* file index */
11871         CHECK_BYTE_COUNT_SUBR(4);
11872         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11873         COUNT_BYTES_SUBR(4);
11874
11875         /* create time */
11876         CHECK_BYTE_COUNT_SUBR(8);
11877         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11878         *bcp -= 8;
11879
11880         /* access time */
11881         CHECK_BYTE_COUNT_SUBR(8);
11882         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11883         *bcp -= 8;
11884
11885         /* last write time */
11886         CHECK_BYTE_COUNT_SUBR(8);
11887         offset = dissect_nt_64bit_time(tvb, tree, offset,
11888                 hf_smb_last_write_time);
11889         *bcp -= 8;
11890
11891         /* last change time */
11892         CHECK_BYTE_COUNT_SUBR(8);
11893         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11894         *bcp -= 8;
11895
11896         /* end of file */
11897         CHECK_BYTE_COUNT_SUBR(8);
11898         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11899         COUNT_BYTES_SUBR(8);
11900
11901         /* allocation size */
11902         CHECK_BYTE_COUNT_SUBR(8);
11903         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11904         COUNT_BYTES_SUBR(8);
11905
11906         /* Extended File Attributes */
11907         CHECK_BYTE_COUNT_SUBR(4);
11908         offset = dissect_file_ext_attr(tvb, tree, offset);
11909         *bcp -= 4;
11910
11911         /* file name len */
11912         CHECK_BYTE_COUNT_SUBR(4);
11913         fn_len = tvb_get_letohl(tvb, offset);
11914         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11915         COUNT_BYTES_SUBR(4);
11916
11917         /* ea length */
11918         CHECK_BYTE_COUNT_SUBR(4);
11919         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11920         COUNT_BYTES_SUBR(4);
11921
11922         /* file name */
11923         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11924         CHECK_STRING_SUBR(fn);
11925         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11926                 fn);
11927         COUNT_BYTES_SUBR(fn_len);
11928
11929         if (check_col(pinfo->cinfo, COL_INFO)) {
11930                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11931                     format_text(fn, strlen(fn)));
11932         }
11933
11934         /* skip to next structure */
11935         if(neo){
11936                 padcnt = (old_offset + neo) - offset;
11937                 if (padcnt < 0) {
11938                         /*
11939                          * XXX - this is bogus; flag it?
11940                          */
11941                         padcnt = 0;
11942                 }
11943                 if (padcnt != 0) {
11944                         CHECK_BYTE_COUNT_SUBR(padcnt);
11945                         COUNT_BYTES_SUBR(padcnt);
11946                 }
11947         }
11948
11949         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
11950         proto_item_set_len(item, offset-old_offset);
11951
11952         *trunc = FALSE;
11953         return offset;
11954 }
11955
11956 static int
11957 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11958     int offset, guint16 *bcp, gboolean *trunc)
11959 {
11960         int fn_len, sfn_len;
11961         const char *fn, *sfn;
11962         int old_offset = offset;
11963         proto_item *item = NULL;
11964         proto_tree *tree = NULL;
11965         smb_info_t *si;
11966         guint32 neo;
11967         int padcnt;
11968
11969         si = (smb_info_t *)pinfo->private_data;
11970
11971         if(parent_tree){
11972                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11973                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11974                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11975         }
11976
11977         /*
11978          * XXX - I have not seen any of these that contain a resume
11979          * key, even though some of the requests had the "return resume
11980          * key" flag set.
11981          */
11982
11983         /* next entry offset */
11984         CHECK_BYTE_COUNT_SUBR(4);
11985         neo = tvb_get_letohl(tvb, offset);
11986         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11987         COUNT_BYTES_SUBR(4);
11988
11989         /* file index */
11990         CHECK_BYTE_COUNT_SUBR(4);
11991         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11992         COUNT_BYTES_SUBR(4);
11993
11994         /* create time */
11995         CHECK_BYTE_COUNT_SUBR(8);
11996         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11997         *bcp -= 8;
11998
11999         /* access time */
12000         CHECK_BYTE_COUNT_SUBR(8);
12001         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
12002         *bcp -= 8;
12003
12004         /* last write time */
12005         CHECK_BYTE_COUNT_SUBR(8);
12006         offset = dissect_nt_64bit_time(tvb, tree, offset,
12007                 hf_smb_last_write_time);
12008         *bcp -= 8;
12009
12010         /* last change time */
12011         CHECK_BYTE_COUNT_SUBR(8);
12012         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
12013         *bcp -= 8;
12014
12015         /* end of file */
12016         CHECK_BYTE_COUNT_SUBR(8);
12017         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12018         COUNT_BYTES_SUBR(8);
12019
12020         /* allocation size */
12021         CHECK_BYTE_COUNT_SUBR(8);
12022         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12023         COUNT_BYTES_SUBR(8);
12024
12025         /* Extended File Attributes */
12026         CHECK_BYTE_COUNT_SUBR(4);
12027         offset = dissect_file_ext_attr(tvb, tree, offset);
12028         *bcp -= 4;
12029
12030         /* file name len */
12031         CHECK_BYTE_COUNT_SUBR(4);
12032         fn_len = tvb_get_letohl(tvb, offset);
12033         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12034         COUNT_BYTES_SUBR(4);
12035
12036         /*
12037          * EA length.
12038          *
12039          * XXX - in one captures, this has the topmost bit set, and the
12040          * rest of the bits have the value 7.  Is the topmost bit being
12041          * set some indication that the value *isn't* the length of
12042          * the EAs?
12043          */
12044         CHECK_BYTE_COUNT_SUBR(4);
12045         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12046         COUNT_BYTES_SUBR(4);
12047
12048         /* short file name len */
12049         CHECK_BYTE_COUNT_SUBR(1);
12050         sfn_len = tvb_get_guint8(tvb, offset);
12051         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12052         COUNT_BYTES_SUBR(1);
12053
12054         /* reserved byte */
12055         CHECK_BYTE_COUNT_SUBR(1);
12056         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12057         COUNT_BYTES_SUBR(1);
12058
12059         /* short file name - it's not always in Unicode */
12060         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12061         CHECK_STRING_SUBR(sfn);
12062         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12063                 sfn);
12064         COUNT_BYTES_SUBR(24);
12065
12066         /* file name */
12067         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12068         CHECK_STRING_SUBR(fn);
12069         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12070                 fn);
12071         COUNT_BYTES_SUBR(fn_len);
12072
12073         if (check_col(pinfo->cinfo, COL_INFO)) {
12074                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12075                     format_text(fn, strlen(fn)));
12076         }
12077
12078         /* skip to next structure */
12079         if(neo){
12080                 padcnt = (old_offset + neo) - offset;
12081                 if (padcnt < 0) {
12082                         /*
12083                          * XXX - this is bogus; flag it?
12084                          */
12085                         padcnt = 0;
12086                 }
12087                 if (padcnt != 0) {
12088                         CHECK_BYTE_COUNT_SUBR(padcnt);
12089                         COUNT_BYTES_SUBR(padcnt);
12090                 }
12091         }
12092
12093         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
12094         proto_item_set_len(item, offset-old_offset);
12095
12096         *trunc = FALSE;
12097         return offset;
12098 }
12099
12100 static int
12101 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12102     int offset, guint16 *bcp, gboolean *trunc)
12103 {
12104         int fn_len;
12105         const char *fn;
12106         int old_offset = offset;
12107         proto_item *item = NULL;
12108         proto_tree *tree = NULL;
12109         smb_info_t *si;
12110         guint32 neo;
12111         int padcnt;
12112
12113         si = (smb_info_t *)pinfo->private_data;
12114
12115         if(parent_tree){
12116                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12117                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12118                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12119         }
12120
12121         /*
12122          * We assume that the presence of a next entry offset implies the
12123          * absence of a resume key, as appears to be the case for 4.3.4.6.
12124          */
12125
12126         /* next entry offset */
12127         CHECK_BYTE_COUNT_SUBR(4);
12128         neo = tvb_get_letohl(tvb, offset);
12129         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12130         COUNT_BYTES_SUBR(4);
12131
12132         /* file index */
12133         CHECK_BYTE_COUNT_SUBR(4);
12134         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12135         COUNT_BYTES_SUBR(4);
12136
12137         /* file name len */
12138         CHECK_BYTE_COUNT_SUBR(4);
12139         fn_len = tvb_get_letohl(tvb, offset);
12140         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12141         COUNT_BYTES_SUBR(4);
12142
12143         /* file name */
12144         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12145         CHECK_STRING_SUBR(fn);
12146         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12147                 fn);
12148         COUNT_BYTES_SUBR(fn_len);
12149
12150         if (check_col(pinfo->cinfo, COL_INFO)) {
12151                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12152                     format_text(fn, strlen(fn)));
12153         }
12154
12155         /* skip to next structure */
12156         if(neo){
12157                 padcnt = (old_offset + neo) - offset;
12158                 if (padcnt < 0) {
12159                         /*
12160                          * XXX - this is bogus; flag it?
12161                          */
12162                         padcnt = 0;
12163                 }
12164                 if (padcnt != 0) {
12165                         CHECK_BYTE_COUNT_SUBR(padcnt);
12166                         COUNT_BYTES_SUBR(padcnt);
12167                 }
12168         }
12169
12170         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
12171         proto_item_set_len(item, offset-old_offset);
12172
12173         *trunc = FALSE;
12174         return offset;
12175 }
12176
12177 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12178
12179 static int
12180 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12181                 proto_tree *tree, int offset, guint16 *bcp,
12182                 gboolean *trunc)
12183 {
12184         smb_info_t *si = pinfo->private_data;
12185         const char *fn;
12186         int fn_len;
12187
12188         /* NextEntryOffset */
12189         CHECK_BYTE_COUNT_SUBR(4);
12190         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
12191         COUNT_BYTES_SUBR(4);
12192         
12193         /* ResumeKey */
12194         CHECK_BYTE_COUNT_SUBR(4);
12195         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
12196         COUNT_BYTES_SUBR(4);
12197
12198         /* End of file (file size) */
12199         CHECK_BYTE_COUNT_SUBR(8);
12200         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
12201         COUNT_BYTES_SUBR(8);
12202
12203         /* Number of bytes */
12204         CHECK_BYTE_COUNT_SUBR(8);
12205         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
12206         COUNT_BYTES_SUBR(8);
12207
12208         /* Last status change */
12209         CHECK_BYTE_COUNT_SUBR(8);
12210         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12211         *bcp -= 8;
12212
12213         /* Last access time */
12214         CHECK_BYTE_COUNT_SUBR(8);
12215         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12216         *bcp -= 8;
12217
12218         /* Last modification time */
12219         CHECK_BYTE_COUNT_SUBR(8);
12220         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12221         *bcp -= 8;
12222
12223         /* File owner uid */
12224         CHECK_BYTE_COUNT_SUBR(8);
12225         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
12226         COUNT_BYTES_SUBR(8);
12227
12228         /* File group gid */
12229         CHECK_BYTE_COUNT_SUBR(8);
12230         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
12231         COUNT_BYTES_SUBR(8);
12232
12233         /* File type */
12234         CHECK_BYTE_COUNT_SUBR(4);
12235         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
12236         COUNT_BYTES_SUBR(4);
12237
12238         /* Major device number */
12239         CHECK_BYTE_COUNT_SUBR(8);
12240         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
12241         COUNT_BYTES_SUBR(8);
12242
12243         /* Minor device number */
12244         CHECK_BYTE_COUNT_SUBR(8);
12245         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12246         COUNT_BYTES_SUBR(8);
12247
12248         /* Unique id */
12249         CHECK_BYTE_COUNT_SUBR(8);
12250         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12251         COUNT_BYTES_SUBR(8);
12252
12253         /* Permissions */
12254         CHECK_BYTE_COUNT_SUBR(8);
12255         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12256         COUNT_BYTES_SUBR(8);
12257
12258         /* Nlinks */
12259         CHECK_BYTE_COUNT_SUBR(8);
12260         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12261         COUNT_BYTES_SUBR(8);
12262
12263         /* Name */
12264
12265         fn = get_unicode_or_ascii_string(
12266                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12267
12268         CHECK_STRING_SUBR(fn);
12269         proto_tree_add_string(
12270                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12271         COUNT_BYTES_SUBR(fn_len);
12272
12273         /* Pad to 4 bytes */
12274
12275         if (offset % 4)
12276                 offset += 4 - (offset % 4);
12277
12278         *trunc = FALSE;
12279         return offset;
12280 }
12281
12282 /*dissect the data block for TRANS2_FIND_FIRST2*/
12283 static int
12284 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12285     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12286 {
12287         smb_info_t *si;
12288
12289         if(!*bcp){
12290                 return offset;
12291         }
12292
12293         si = (smb_info_t *)pinfo->private_data;
12294         switch(si->info_level){
12295         case 1:         /*Info Standard*/
12296                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12297                     trunc);
12298                 break;
12299         case 2:         /*Info Query EA Size*/
12300                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12301                     trunc);
12302                 break;
12303         case 3:         /*Info Query EAs From List same as
12304                                 InfoQueryEASize*/
12305                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12306                     trunc);
12307                 break;
12308         case 0x0101:    /*Find File Directory Info*/
12309                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12310                     trunc);
12311                 break;
12312         case 0x0102:    /*Find File Full Directory Info*/
12313                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12314                     trunc);
12315                 break;
12316         case 0x0103:    /*Find File Names Info*/
12317                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12318                     trunc);
12319                 break;
12320         case 0x0104:    /*Find File Both Directory Info*/
12321                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12322                     trunc);
12323                 break;
12324         case 0x0202:    /*Find File UNIX*/
12325                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12326                     trunc);
12327                 break;
12328         default:        /* unknown info level */
12329                 *trunc = FALSE;
12330                 break;
12331         }
12332         return offset;
12333 }
12334
12335
12336 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
12337 static int
12338 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12339 {
12340         guint32 mask;
12341         proto_item *item = NULL;
12342         proto_tree *tree = NULL;
12343
12344         mask = tvb_get_letohl(tvb, offset);
12345
12346         if(parent_tree){
12347                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12348                         "FS Attributes: 0x%08x", mask);
12349                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12350         }
12351
12352         /* case sensitive search */
12353         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12354                 tvb, offset, 4, mask);
12355         /* case preserved names */
12356         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12357                 tvb, offset, 4, mask);
12358         /* unicode on disk */
12359         proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
12360                 tvb, offset, 4, mask);
12361         /* persistent acls */
12362         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12363                 tvb, offset, 4, mask);
12364         /* file compression */
12365         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12366                 tvb, offset, 4, mask);
12367         /* volume quotas */
12368         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12369                 tvb, offset, 4, mask);
12370         /* sparse files */
12371         proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
12372                 tvb, offset, 4, mask);
12373         /* reparse points */
12374         proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
12375                 tvb, offset, 4, mask);
12376         /* remote storage */
12377         proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
12378                 tvb, offset, 4, mask);
12379         /* lfn apis */
12380         proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
12381                 tvb, offset, 4, mask);
12382         /* volume is compressed */
12383         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12384                 tvb, offset, 4, mask);
12385         /* support oids */
12386         proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
12387                 tvb, offset, 4, mask);
12388         /* encryption */
12389         proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
12390                 tvb, offset, 4, mask);
12391         /* named streams */
12392         proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
12393                 tvb, offset, 4, mask);
12394         /* read only volume */
12395         proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
12396                 tvb, offset, 4, mask);
12397
12398
12399         offset += 4;
12400         return offset;
12401 }
12402
12403
12404 static int
12405 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12406 {
12407         guint32 mask;
12408         proto_item *item = NULL;
12409         proto_tree *tree = NULL;
12410
12411         mask = tvb_get_letohl(tvb, offset);
12412
12413         if(parent_tree){
12414                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12415                         "Device Characteristics: 0x%08x", mask);
12416                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12417         }
12418
12419         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12420                 tvb, offset, 4, mask);
12421         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12422                 tvb, offset, 4, mask);
12423         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12424                 tvb, offset, 4, mask);
12425         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12426                 tvb, offset, 4, mask);
12427         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12428                 tvb, offset, 4, mask);
12429         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12430                 tvb, offset, 4, mask);
12431         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12432                 tvb, offset, 4, mask);
12433
12434         offset += 4;
12435         return offset;
12436 }
12437
12438 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12439
12440 static const true_false_string tfs_smb_mac_access_ctrl = {
12441   "Macintosh Access Control Supported",
12442   "Macintosh Access Control Not Supported"
12443 };
12444
12445 static const true_false_string tfs_smb_mac_getset_comments = {
12446   "Macintosh Get & Set Comments Supported",
12447   "Macintosh Get & Set Comments Not Supported"
12448 };
12449
12450 static const true_false_string tfs_smb_mac_desktopdb_calls = {
12451   "Macintosh Get & Set Desktop Database Info Supported",
12452   "Macintosh Get & Set Desktop Database Info Supported"
12453 };
12454
12455 static const true_false_string tfs_smb_mac_unique_ids = {
12456   "Macintosh Unique IDs Supported",
12457   "Macintosh Unique IDs Not Supported"
12458 };
12459
12460 static const true_false_string tfs_smb_mac_streams = {
12461   "Macintosh and Streams Extensions Not Supported",
12462   "Macintosh and Streams Extensions Supported"
12463 };
12464
12465 static int
12466 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12467     int offset, guint16 *bcp)
12468 {
12469         smb_info_t *si;
12470         int fn_len, vll, fnl;
12471         const char *fn;
12472         guint support = 0;
12473         proto_item *item = NULL;
12474         proto_tree *ti = NULL;
12475
12476         if(!*bcp){
12477                 return offset;
12478         }
12479
12480         si = (smb_info_t *)pinfo->private_data;
12481         switch(si->info_level){
12482         case 1:         /* SMB_INFO_ALLOCATION */
12483                 /* filesystem id */
12484                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12485                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12486                 COUNT_BYTES_TRANS_SUBR(4);
12487
12488                 /* sectors per unit */
12489                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12490                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12491                 COUNT_BYTES_TRANS_SUBR(4);
12492
12493                 /* units */
12494                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12495                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12496                 COUNT_BYTES_TRANS_SUBR(4);
12497
12498                 /* avail units */
12499                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12500                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12501                 COUNT_BYTES_TRANS_SUBR(4);
12502
12503                 /* bytes per sector, only 16bit integer here */
12504                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12505                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12506                 COUNT_BYTES_TRANS_SUBR(2);
12507
12508                 break;
12509         case 2:         /* SMB_INFO_VOLUME */
12510                 /* volume serial number */
12511                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12512                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12513                 COUNT_BYTES_TRANS_SUBR(4);
12514
12515                 /* volume label length, only one byte here */
12516                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12517                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12518                 COUNT_BYTES_TRANS_SUBR(1);
12519
12520                 /* label */
12521                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12522                 CHECK_STRING_TRANS_SUBR(fn);
12523                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12524                         fn);
12525                 COUNT_BYTES_TRANS_SUBR(fn_len);
12526
12527                 break;
12528         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12529         case 1002:      /* SMB_FS_LABEL_INFORMATION */
12530                 /* volume label length */
12531                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12532                 vll = tvb_get_letohl(tvb, offset);
12533                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12534                 COUNT_BYTES_TRANS_SUBR(4);
12535
12536                 /* label */
12537                 fn_len = vll;
12538                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12539                 CHECK_STRING_TRANS_SUBR(fn);
12540                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12541                         fn);
12542                 COUNT_BYTES_TRANS_SUBR(fn_len);
12543
12544                 break;
12545         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12546         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
12547                 /* create time */
12548                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12549                 offset = dissect_nt_64bit_time(tvb, tree, offset,
12550                         hf_smb_create_time);
12551                 *bcp -= 8;
12552
12553                 /* volume serial number */
12554                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12555                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12556                 COUNT_BYTES_TRANS_SUBR(4);
12557
12558                 /* volume label length */
12559                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12560                 vll = tvb_get_letohl(tvb, offset);
12561                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12562                 COUNT_BYTES_TRANS_SUBR(4);
12563
12564                 /* 2 reserved bytes */
12565                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12566                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12567                 COUNT_BYTES_TRANS_SUBR(2);
12568
12569                 /* label */
12570                 fn_len = vll;
12571                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12572                 CHECK_STRING_TRANS_SUBR(fn);
12573                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12574                         fn);
12575                 COUNT_BYTES_TRANS_SUBR(fn_len);
12576
12577                 break;
12578         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12579         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12580                 /* allocation size */
12581                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12582                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12583                 COUNT_BYTES_TRANS_SUBR(8);
12584
12585                 /* free allocation units */
12586                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12587                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12588                 COUNT_BYTES_TRANS_SUBR(8);
12589
12590                 /* sectors per unit */
12591                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12592                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12593                 COUNT_BYTES_TRANS_SUBR(4);
12594
12595                 /* bytes per sector */
12596                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12597                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12598                 COUNT_BYTES_TRANS_SUBR(4);
12599
12600                 break;
12601         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12602         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12603                 /* device type */
12604                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12605                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12606                 COUNT_BYTES_TRANS_SUBR(4);
12607
12608                 /* device characteristics */
12609                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12610                 offset = dissect_device_characteristics(tvb, tree, offset);
12611                 *bcp -= 4;
12612
12613                 break;
12614         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12615         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12616                 /* FS attributes */
12617                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12618                 offset = dissect_fs_attributes(tvb, tree, offset);
12619                 *bcp -= 4;
12620
12621                 /* max name len */
12622                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12623                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12624                 COUNT_BYTES_TRANS_SUBR(4);
12625
12626                 /* fs name length */
12627                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12628                 fnl = tvb_get_letohl(tvb, offset);
12629                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12630                 COUNT_BYTES_TRANS_SUBR(4);
12631
12632                 /* label */
12633                 fn_len = fnl;
12634                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12635                 CHECK_STRING_TRANS_SUBR(fn);
12636                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12637                         fn);
12638                 COUNT_BYTES_TRANS_SUBR(fn_len);
12639
12640                 break;
12641         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
12642                 proto_item *item = NULL;
12643                 proto_tree *subtree = NULL;
12644                 guint32 caps_lo, caps_hi;
12645
12646                 /* MajorVersionNumber */
12647                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12648                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
12649                 COUNT_BYTES_TRANS_SUBR(2);
12650
12651                 /* MinorVersionNumber */
12652                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12653                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
12654                 COUNT_BYTES_TRANS_SUBR(2);
12655
12656                 /* Capability */
12657
12658                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12659
12660                 caps_lo = tvb_get_letohl(tvb, offset);
12661                 caps_hi = tvb_get_letohl(tvb, offset + 4);
12662
12663                 if (tree) {
12664                         item = proto_tree_add_text(
12665                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
12666                                 caps_hi, caps_lo);
12667                         subtree = proto_item_add_subtree(
12668                                 item, ett_smb_unix_capabilities);
12669                 }
12670
12671                 proto_tree_add_boolean(
12672                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
12673                         caps_lo);
12674
12675                 proto_tree_add_boolean(
12676                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
12677                         caps_lo);
12678
12679                 COUNT_BYTES_TRANS_SUBR(8);
12680
12681                 break;
12682         }
12683         case 0x301:     /* MAC_QUERY_FS_INFO */
12684                 /* Create time */
12685                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12686                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
12687                 *bcp -= 8;
12688                 /* Modify Time */
12689                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12690                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
12691                 *bcp -= 8;
12692                 /* Backup Time */
12693                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12694                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
12695                 *bcp -= 8;
12696                 /* Allocation blocks */
12697                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12698                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
12699                                     offset,
12700                                     4, TRUE);
12701                 COUNT_BYTES_TRANS_SUBR(4);
12702                 /* Allocation Block Size */
12703                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12704                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
12705                                     offset, 4, TRUE);
12706                 COUNT_BYTES_TRANS_SUBR(4);
12707                 /* Free Block Count */
12708                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12709                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
12710                                     offset, 4, TRUE);
12711                 COUNT_BYTES_TRANS_SUBR(4);
12712                 /* Finder Info ... */
12713                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
12714                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
12715                                             offset, 32,
12716                                             tvb_get_ptr(tvb, offset,32),
12717                                             "Finder Info: %s",
12718                                             tvb_format_text(tvb, offset, 32));
12719                 COUNT_BYTES_TRANS_SUBR(32);
12720                 /* Number Files */
12721                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12722                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
12723                                     offset, 4, TRUE);
12724                 COUNT_BYTES_TRANS_SUBR(4);
12725                 /* Number of Root Directories */
12726                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12727                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
12728                                     offset, 4, TRUE);
12729                 COUNT_BYTES_TRANS_SUBR(4);
12730                 /* Number of files */
12731                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12732                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
12733                                     offset, 4, TRUE);
12734                 COUNT_BYTES_TRANS_SUBR(4);
12735                 /* Dir Count */
12736                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12737                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
12738                                     offset, 4, TRUE);
12739                 COUNT_BYTES_TRANS_SUBR(4);
12740                 /* Mac Support Flags */
12741                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12742                 support = tvb_get_ntohl(tvb, offset);
12743                 item = proto_tree_add_text(tree, tvb, offset, 4,
12744                                            "Mac Support Flags: 0x%08x", support);
12745                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
12746                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
12747                                        tvb, offset, 4, support);
12748                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
12749                                        tvb, offset, 4, support);
12750                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
12751                                        tvb, offset, 4, support);
12752                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
12753                                        tvb, offset, 4, support);
12754                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
12755                                        tvb, offset, 4, support);
12756                 COUNT_BYTES_TRANS_SUBR(4);
12757                 break;
12758         case 1006:      /* QUERY_FS_QUOTA_INFO */
12759                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12760                 break;
12761         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12762                 /* allocation size */
12763                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12764                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12765                 COUNT_BYTES_TRANS_SUBR(8);
12766
12767                 /* caller free allocation units */
12768                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12769                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12770                 COUNT_BYTES_TRANS_SUBR(8);
12771
12772                 /* actual free allocation units */
12773                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12774                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12775                 COUNT_BYTES_TRANS_SUBR(8);
12776
12777                 /* sectors per unit */
12778                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12779                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12780                 COUNT_BYTES_TRANS_SUBR(4);
12781
12782                 /* bytes per sector */
12783                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12784                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12785                 COUNT_BYTES_TRANS_SUBR(4);
12786                 break;
12787         case 1008: /* Query Object ID is GUID plus unknown data */ {
12788                 e_uuid_t fs_id;
12789                 char uuid_str[DCERPC_UUID_STR_LEN]; 
12790                 int uuid_str_len;
12791                 guint8 drep = 0x10;
12792                 
12793                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
12794
12795                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
12796
12797                 uuid_str_len = snprintf(
12798                         uuid_str, DCERPC_UUID_STR_LEN, 
12799                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
12800                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
12801                         fs_id.Data4[0], fs_id.Data4[1],
12802                         fs_id.Data4[2], fs_id.Data4[3],
12803                         fs_id.Data4[4], fs_id.Data4[5],
12804                         fs_id.Data4[6], fs_id.Data4[7]);
12805
12806                 proto_tree_add_string_format(
12807                         tree, hf_smb_fs_guid, tvb,
12808                         offset, 16, uuid_str, "GUID: %s", uuid_str);
12809
12810                 COUNT_BYTES_TRANS_SUBR(16);
12811                 break;
12812             }
12813         }
12814
12815         return offset;
12816 }
12817
12818 static int
12819 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12820     proto_tree *parent_tree)
12821 {
12822         proto_item *item = NULL;
12823         proto_tree *tree = NULL;
12824         smb_info_t *si;
12825         smb_transact2_info_t *t2i;
12826         int count;
12827         gboolean trunc;
12828         int offset = 0;
12829         guint16 dc;
12830
12831         dc = tvb_reported_length(tvb);
12832
12833         si = (smb_info_t *)pinfo->private_data;
12834         if (si->sip != NULL)
12835                 t2i = si->sip->extra_info;
12836         else
12837                 t2i = NULL;
12838
12839         if(parent_tree){
12840                 if (t2i != NULL && t2i->subcmd != -1) {
12841                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12842                                 "%s Data",
12843                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12844                                         "Unknown (0x%02x)"));
12845                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12846                 } else {
12847                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12848                                 "Unknown Transaction2 Data");
12849                 }
12850         }
12851
12852         if (t2i == NULL) {
12853                 offset += dc;
12854                 return offset;
12855         }
12856         switch(t2i->subcmd){
12857         case 0x00:      /*TRANS2_OPEN2*/
12858                 /* XXX not implemented yet. See SNIA doc */
12859                 break;
12860         case 0x01:      /*TRANS2_FIND_FIRST2*/
12861                 /* returned data */
12862                 count = si->info_count;
12863
12864                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12865                         col_append_fstr(pinfo->cinfo, COL_INFO,
12866                         ", Files:");
12867                 }
12868
12869                 while(count--){
12870                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12871                                 offset, &dc, &trunc);
12872                         if (trunc)
12873                                 break;
12874                 }
12875                 break;
12876         case 0x02:      /*TRANS2_FIND_NEXT2*/
12877                 /* returned data */
12878                 count = si->info_count;
12879
12880                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12881                         col_append_fstr(pinfo->cinfo, COL_INFO,
12882                         ", Files:");
12883                 }
12884
12885                 while(count--){
12886                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12887                                 offset, &dc, &trunc);
12888                         if (trunc)
12889                                 break;
12890                 }
12891                 break;
12892         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12893                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12894                 break;
12895         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12896                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12897                 break;
12898         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12899                 /* no data in this response */
12900                 break;
12901         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12902                 /* identical to QUERY_PATH_INFO */
12903                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12904                 break;
12905         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12906                 /* no data in this response */
12907                 break;
12908         case 0x09:      /*TRANS2_FSCTL*/
12909                 /* XXX dont know how to dissect this one (yet)*/
12910
12911                 /*
12912                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12913                  * Extensions Version 3.0, Document Version 1.11,
12914                  * July 19, 1990" says this this contains a
12915                  * "File system specific return data block".
12916                  * (That means we may not be able to dissect it in any
12917                  * case.)
12918                  */
12919                 break;
12920         case 0x0a:      /*TRANS2_IOCTL2*/
12921                 /* XXX dont know how to dissect this one (yet)*/
12922
12923                 /*
12924                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12925                  * Extensions Version 3.0, Document Version 1.11,
12926                  * July 19, 1990" says this this contains a
12927                  * "Device/function specific return data block".
12928                  * (That means we may not be able to dissect it in any
12929                  * case.)
12930                  */
12931                 break;
12932         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12933                 /* XXX dont know how to dissect this one (yet)*/
12934
12935                 /*
12936                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12937                  * Extensions Version 3.0, Document Version 1.11,
12938                  * July 19, 1990" says this this contains "the level
12939                  * dependent information about the changes which
12940                  * occurred".
12941                  */
12942                 break;
12943         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12944                 /* XXX dont know how to dissect this one (yet)*/
12945
12946                 /*
12947                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12948                  * Extensions Version 3.0, Document Version 1.11,
12949                  * July 19, 1990" says this this contains "the level
12950                  * dependent information about the changes which
12951                  * occurred".
12952                  */
12953                 break;
12954         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12955                 /* no data in this response */
12956                 break;
12957         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12958                 /* XXX dont know how to dissect this one (yet)*/
12959                 break;
12960         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12961                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12962                 break;
12963         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12964                 /* the SNIA spec appears to say the response has no data */
12965                 break;
12966         case -1:
12967                 /*
12968                  * We don't know what the matching request was; don't
12969                  * bother putting anything else into the tree for the data.
12970                  */
12971                 offset += dc;
12972                 dc = 0;
12973                 break;
12974         }
12975
12976         /* ooops there were data we didnt know how to process */
12977         if(dc != 0){
12978                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12979                 offset += dc;
12980         }
12981
12982         return offset;
12983 }
12984
12985
12986 static void
12987 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12988 {
12989         proto_item *item = NULL;
12990         proto_tree *tree = NULL;
12991         smb_info_t *si;
12992         smb_transact2_info_t *t2i;
12993         guint16 fid;
12994         int lno;
12995         int offset = 0;
12996         int pc;
12997
12998         pc = tvb_reported_length(tvb);
12999
13000         si = (smb_info_t *)pinfo->private_data;
13001         if (si->sip != NULL)
13002                 t2i = si->sip->extra_info;
13003         else
13004                 t2i = NULL;
13005
13006         if(parent_tree){
13007                 if (t2i != NULL && t2i->subcmd != -1) {
13008                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13009                                 "%s Parameters",
13010                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13011                                                 "Unknown (0x%02x)"));
13012                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13013                 } else {
13014                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13015                                 "Unknown Transaction2 Parameters");
13016                 }
13017         }
13018
13019         if (t2i == NULL) {
13020                 offset += pc;
13021                 return;
13022         }
13023         switch(t2i->subcmd){
13024         case 0x00:      /*TRANS2_OPEN2*/
13025                 /* fid */
13026                 fid = tvb_get_letohs(tvb, offset);
13027                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13028                 offset += 2;
13029
13030                 /*
13031                  * XXX - Microsoft Networks SMB File Sharing Protocol
13032                  * Extensions Version 3.0, Document Version 1.11,
13033                  * July 19, 1990 says that the file attributes, create
13034                  * time (which it says is the last modification time),
13035                  * data size, granted access, file type, and IPC state
13036                  * are returned only if bit 0 is set in the open flags,
13037                  * and that the EA length is returned only if bit 3
13038                  * is set in the open flags.  Does that mean that,
13039                  * at least in that SMB dialect, those fields are not
13040                  * present in the reply parameters if the bits in
13041                  * question aren't set?
13042                  */
13043
13044                 /* File Attributes */
13045                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13046
13047                 /* create time */
13048                 offset = dissect_smb_datetime(tvb, tree, offset,
13049                         hf_smb_create_time,
13050                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13051
13052                 /* data size */
13053                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13054                 offset += 4;
13055
13056                 /* granted access */
13057                 offset = dissect_access(tvb, tree, offset, "Granted");
13058
13059                 /* File Type */
13060                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13061                 offset += 2;
13062
13063                 /* IPC State */
13064                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13065
13066                 /* open_action */
13067                 offset = dissect_open_action(tvb, tree, offset);
13068
13069                 /* server unique file ID */
13070                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13071                 offset += 4;
13072
13073                 /* ea error offset, only a 16 bit integer here */
13074                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13075                 offset += 2;
13076
13077                 /* ea length */
13078                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13079                 offset += 4;
13080
13081                 break;
13082         case 0x01:      /*TRANS2_FIND_FIRST2*/
13083                 /* Find First2 information level */
13084                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13085
13086                 /* sid */
13087                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13088                 offset += 2;
13089
13090                 /* search count */
13091                 si->info_count = tvb_get_letohs(tvb, offset);
13092                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13093                 offset += 2;
13094
13095                 /* end of search */
13096                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13097                 offset += 2;
13098
13099                 /* ea error offset, only a 16 bit integer here */
13100                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13101                 offset += 2;
13102
13103                 /* last name offset */
13104                 lno = tvb_get_letohs(tvb, offset);
13105                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13106                 offset += 2;
13107
13108                 break;
13109         case 0x02:      /*TRANS2_FIND_NEXT2*/
13110                 /* search count */
13111                 si->info_count = tvb_get_letohs(tvb, offset);
13112                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13113                 offset += 2;
13114
13115                 /* end of search */
13116                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13117                 offset += 2;
13118
13119                 /* ea_error_offset, only a 16 bit integer here*/
13120                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13121                 offset += 2;
13122
13123                 /* last name offset */
13124                 lno = tvb_get_letohs(tvb, offset);
13125                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13126                 offset += 2;
13127
13128                 break;
13129         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13130                 /* no parameter block here */
13131                 break;
13132         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13133                 /* ea_error_offset, only a 16 bit integer here*/
13134                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13135                 offset += 2;
13136
13137                 break;
13138         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13139                 /* ea_error_offset, only a 16 bit integer here*/
13140                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13141                 offset += 2;
13142
13143                 break;
13144         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13145                 /* ea_error_offset, only a 16 bit integer here*/
13146                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13147                 offset += 2;
13148
13149                 break;
13150         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13151                 /* ea_error_offset, only a 16 bit integer here*/
13152                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13153                 offset += 2;
13154
13155                 break;
13156         case 0x09:      /*TRANS2_FSCTL*/
13157                 /* XXX dont know how to dissect this one (yet)*/
13158
13159                 /*
13160                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13161                  * Extensions Version 3.0, Document Version 1.11,
13162                  * July 19, 1990" says this this contains a
13163                  * "File system specific return parameter block".
13164                  * (That means we may not be able to dissect it in any
13165                  * case.)
13166                  */
13167                 break;
13168         case 0x0a:      /*TRANS2_IOCTL2*/
13169                 /* XXX dont know how to dissect this one (yet)*/
13170
13171                 /*
13172                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13173                  * Extensions Version 3.0, Document Version 1.11,
13174                  * July 19, 1990" says this this contains a
13175                  * "Device/function specific return parameter block".
13176                  * (That means we may not be able to dissect it in any
13177                  * case.)
13178                  */
13179                 break;
13180         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13181                 /* Find Notify information level */
13182                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13183
13184                 /* Monitor handle */
13185                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13186                 offset += 2;
13187
13188                 /* Change count */
13189                 si->info_count = tvb_get_letohs(tvb, offset);
13190                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13191                 offset += 2;
13192
13193                 /* ea_error_offset, only a 16 bit integer here*/
13194                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13195                 offset += 2;
13196
13197                 break;
13198         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13199                 /* Find Notify information level */
13200                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13201
13202                 /* Change count */
13203                 si->info_count = tvb_get_letohs(tvb, offset);
13204                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13205                 offset += 2;
13206
13207                 /* ea_error_offset, only a 16 bit integer here*/
13208                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13209                 offset += 2;
13210
13211                 break;
13212         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13213                 /* ea error offset, only a 16 bit integer here */
13214                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13215                 offset += 2;
13216
13217                 break;
13218         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13219                 /* XXX dont know how to dissect this one (yet)*/
13220                 break;
13221         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13222                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13223                 break;
13224         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13225                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13226                 break;
13227         case -1:
13228                 /*
13229                  * We don't know what the matching request was; don't
13230                  * bother putting anything else into the tree for the data.
13231                  */
13232                 offset += pc;
13233                 break;
13234         }
13235
13236         /* ooops there were data we didnt know how to process */
13237         if(offset<pc){
13238                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13239                 offset += pc-offset;
13240         }
13241 }
13242
13243
13244 static int
13245 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13246 {
13247         guint8 sc, wc;
13248         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13249         smb_info_t *si;
13250         smb_transact2_info_t *t2i = NULL;
13251         guint16 bc;
13252         int padcnt;
13253         gboolean dissected_trans;
13254         fragment_data *r_fd = NULL;
13255         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13256         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13257         gboolean save_fragmented;
13258
13259         si = (smb_info_t *)pinfo->private_data;
13260
13261         switch(si->cmd){
13262         case SMB_COM_TRANSACTION2:
13263                 /* transaction2 */
13264                 if (si->sip != NULL) {
13265                         t2i = si->sip->extra_info;
13266                 } else
13267                         t2i = NULL;
13268                 if (t2i == NULL) {
13269                         /*
13270                          * We didn't see the matching request, so we don't
13271                          * know what type of transaction this is.
13272                          */
13273                         proto_tree_add_text(tree, tvb, 0, 0,
13274                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13275                         if (check_col(pinfo->cinfo, COL_INFO)) {
13276                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13277                         }
13278                 } else {
13279                         si->info_level = t2i->info_level;
13280                         if (t2i->subcmd == -1) {
13281                                 /*
13282                                  * We didn't manage to extract the subcommand
13283                                  * from the matching request (perhaps because
13284                                  * the frame was short), so we don't know what
13285                                  * type of transaction this is.
13286                                  */
13287                                 proto_tree_add_text(tree, tvb, 0, 0,
13288                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13289                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13290                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13291                                 }
13292                         } else {
13293                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13294                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13295                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13296                                                 val_to_str(t2i->subcmd,
13297                                                         trans2_cmd_vals,
13298                                                         "<unknown (0x%02x)>"));
13299                                 }
13300                         }
13301                 }
13302                 break;
13303         }
13304
13305         WORD_COUNT;
13306
13307         /* total param count, only a 16bit integer here */
13308         tp = tvb_get_letohs(tvb, offset);
13309         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
13310         offset += 2;
13311
13312         /* total data count, only a 16 bit integer here */
13313         td = tvb_get_letohs(tvb, offset);
13314         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
13315         offset += 2;
13316
13317         /* 2 reserved bytes */
13318         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13319         offset += 2;
13320
13321         /* param count */
13322         pc = tvb_get_letohs(tvb, offset);
13323         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13324         offset += 2;
13325
13326         /* param offset */
13327         po = tvb_get_letohs(tvb, offset);
13328         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13329         offset += 2;
13330
13331         /* param disp */
13332         pd = tvb_get_letohs(tvb, offset);
13333         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13334         offset += 2;
13335
13336         /* data count */
13337         dc = tvb_get_letohs(tvb, offset);
13338         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13339         offset += 2;
13340
13341         /* data offset */
13342         od = tvb_get_letohs(tvb, offset);
13343         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13344         offset += 2;
13345
13346         /* data disp */
13347         dd = tvb_get_letohs(tvb, offset);
13348         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13349         offset += 2;
13350
13351         /* setup count */
13352         sc = tvb_get_guint8(tvb, offset);
13353         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13354         offset += 1;
13355
13356         /* reserved byte */
13357         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13358         offset += 1;
13359
13360
13361         /* if there were any setup bytes, put them in a tvb for later */
13362         if(sc){
13363                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13364                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13365                 } else {
13366                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13367                 }
13368                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13369         } else {
13370                 s_tvb = NULL;
13371                 sp_tvb=NULL;
13372         }
13373         offset += 2*sc;
13374
13375
13376         BYTE_COUNT;
13377
13378
13379         /* reassembly of SMB Transaction data payload.
13380            In this section we do reassembly of both the data and parameters
13381            blocks of the SMB transaction command.
13382         */
13383         save_fragmented = pinfo->fragmented;
13384         /* do we need reassembly? */
13385         if( (td!=dc) || (tp!=pc) ){
13386                 /* oh yeah, either data or parameter section needs
13387                    reassembly
13388                 */
13389                 pinfo->fragmented = TRUE;
13390                 if(smb_trans_reassembly){
13391                         /* ...and we were told to do reassembly */
13392                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13393                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13394                                                              po, pc, pd, td+tp);
13395
13396                         }
13397                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13398                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13399                                                              od, dc, dd+tp, td+tp);
13400                         }
13401                 }
13402         }
13403
13404         /* if we got a reassembled fd structure from the reassembly routine we must
13405            create pd_tvb from it
13406         */
13407         if(r_fd){
13408                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13409                                              r_fd->datalen);
13410                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13411                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13412                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13413         }
13414
13415
13416         if(pd_tvb){
13417                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13418                 if(tp){
13419                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13420                 }
13421                 if(td){
13422                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13423                 }
13424         } else {
13425                 /* It was not reassembled. Do as best as we can.
13426                  * in this case we always try to dissect the stuff if
13427                  * data and param displacement is 0. i.e. for the first
13428                  * (and maybe only) packet.
13429                  */
13430                 if( (pd==0) && (dd==0) ){
13431                         int min;
13432                         int reported_min;
13433                         min = MIN(pc,tvb_length_remaining(tvb,po));
13434                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13435                         if(min && reported_min) {
13436                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13437                         }
13438                         min = MIN(dc,tvb_length_remaining(tvb,od));
13439                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13440                         if(min && reported_min) {
13441                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13442                         }
13443                         /*
13444                          * A tvbuff containing the parameters
13445                          * and the data.
13446                          * XXX - check pc and dc as well?
13447                          */
13448                         if (tvb_length_remaining(tvb, po)){
13449                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13450                         }
13451                 }
13452         }
13453
13454
13455
13456         /* parameters */
13457         if(po>offset){
13458                 /* We have some padding bytes.
13459                 */
13460                 padcnt = po-offset;
13461                 if (padcnt > bc)
13462                         padcnt = bc;
13463                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13464                 COUNT_BYTES(padcnt);
13465         }
13466         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
13467                 /* TRANSACTION2 parameters*/
13468                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
13469         }
13470         COUNT_BYTES(pc);
13471
13472
13473         /* data */
13474         if(od>offset){
13475                 /* We have some initial padding bytes.
13476                 */
13477                 padcnt = od-offset;
13478                 if (padcnt > bc)
13479                         padcnt = bc;
13480                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13481                 COUNT_BYTES(padcnt);
13482         }
13483         /*
13484          * If the data count is bigger than the count of bytes
13485          * remaining, clamp it so that the count of bytes remaining
13486          * doesn't go negative.
13487          */
13488         if (dc > bc)
13489                 dc = bc;
13490         COUNT_BYTES(dc);
13491
13492
13493
13494         /* from now on, everything is in separate tvbuffs so we dont count
13495            the bytes with COUNT_BYTES any more.
13496            neither do we reference offset any more (which by now points to the
13497            first byte AFTER this PDU */
13498
13499
13500         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
13501                 /* TRANSACTION2 parameters*/
13502                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
13503         }
13504
13505
13506         if(si->cmd==SMB_COM_TRANSACTION){
13507                 smb_transact_info_t *tri;
13508
13509                 dissected_trans = FALSE;
13510                 if (si->sip != NULL)
13511                         tri = si->sip->extra_info;
13512                 else
13513                         tri = NULL;
13514                 if (tri != NULL) {
13515                         switch(tri->subcmd){
13516
13517                         case TRANSACTION_PIPE:
13518                                 /* This function is safe to call for
13519                                    s_tvb==sp_tvb==NULL, i.e. if we don't
13520                                    know them at this point.
13521                                    It's also safe to call if "p_tvb"
13522                                    or "d_tvb" are null.
13523                                 */
13524                                 if( pd_tvb) {
13525                                         dissected_trans = dissect_pipe_smb(
13526                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
13527                                                 d_tvb, NULL, pinfo, top_tree);
13528                                 }
13529                                 break;
13530
13531                         case TRANSACTION_MAILSLOT:
13532                                 /* This one should be safe to call
13533                                    even if s_tvb and sp_tvb is NULL
13534                                 */
13535                                 if(d_tvb){
13536                                         dissected_trans = dissect_mailslot_smb(
13537                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
13538                                                 top_tree);
13539                                 }
13540                                 break;
13541                         }
13542                 }
13543                 if (!dissected_trans) {
13544                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
13545                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13546                 }
13547         }
13548
13549
13550         if( (p_tvb==0) && (d_tvb==0) ){
13551                 if(check_col(pinfo->cinfo, COL_INFO)){
13552                         col_append_str(pinfo->cinfo, COL_INFO,
13553                                        "[transact continuation]");
13554                 }
13555         }
13556
13557         pinfo->fragmented = save_fragmented;
13558         END_OF_SMB
13559
13560         return offset;
13561 }
13562
13563
13564 static int
13565 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13566 {
13567         guint8 wc;
13568         guint16 bc;
13569
13570         WORD_COUNT;
13571
13572         /* Monitor handle */
13573         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13574         offset += 2;
13575
13576         BYTE_COUNT;
13577
13578         END_OF_SMB
13579
13580         return offset;
13581 }
13582
13583 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13584    END Transaction/Transaction2 Primary and secondary requests
13585    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13586
13587
13588 static int
13589 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13590 {
13591         guint8 wc;
13592         guint16 bc;
13593
13594         WORD_COUNT;
13595
13596         if (wc != 0) {
13597                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13598                 offset += wc*2;
13599         }
13600
13601         BYTE_COUNT;
13602
13603         if (bc != 0) {
13604                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13605                 offset += bc;
13606                 bc = 0;
13607         }
13608
13609         END_OF_SMB
13610
13611         return offset;
13612 }
13613
13614 typedef struct _smb_function {
13615        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13616        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13617 } smb_function;
13618
13619 static smb_function smb_dissector[256] = {
13620   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13621   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13622   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13623   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13624   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13625   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13626   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13627   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13628   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13629   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13630   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13631   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13632   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13633   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13634   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13635   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13636
13637   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13638   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13639   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13640   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13641   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13642   /* 0x15 */  {dissect_unknown, dissect_unknown},
13643   /* 0x16 */  {dissect_unknown, dissect_unknown},
13644   /* 0x17 */  {dissect_unknown, dissect_unknown},
13645   /* 0x18 */  {dissect_unknown, dissect_unknown},
13646   /* 0x19 */  {dissect_unknown, dissect_unknown},
13647   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13648   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13649   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13650   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13651   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13652   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13653
13654   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13655   /* 0x21 */  {dissect_unknown, dissect_unknown},
13656   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13657   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13658   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13659   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13660   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13661   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13662   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13663   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13664   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13665   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13666   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13667   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13668   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13669   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13670
13671   /* 0x30 */  {dissect_unknown, dissect_unknown},
13672   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13673   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13674   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13675   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13676   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13677   /* 0x36 */  {dissect_unknown, dissect_unknown},
13678   /* 0x37 */  {dissect_unknown, dissect_unknown},
13679   /* 0x38 */  {dissect_unknown, dissect_unknown},
13680   /* 0x39 */  {dissect_unknown, dissect_unknown},
13681   /* 0x3a */  {dissect_unknown, dissect_unknown},
13682   /* 0x3b */  {dissect_unknown, dissect_unknown},
13683   /* 0x3c */  {dissect_unknown, dissect_unknown},
13684   /* 0x3d */  {dissect_unknown, dissect_unknown},
13685   /* 0x3e */  {dissect_unknown, dissect_unknown},
13686   /* 0x3f */  {dissect_unknown, dissect_unknown},
13687
13688   /* 0x40 */  {dissect_unknown, dissect_unknown},
13689   /* 0x41 */  {dissect_unknown, dissect_unknown},
13690   /* 0x42 */  {dissect_unknown, dissect_unknown},
13691   /* 0x43 */  {dissect_unknown, dissect_unknown},
13692   /* 0x44 */  {dissect_unknown, dissect_unknown},
13693   /* 0x45 */  {dissect_unknown, dissect_unknown},
13694   /* 0x46 */  {dissect_unknown, dissect_unknown},
13695   /* 0x47 */  {dissect_unknown, dissect_unknown},
13696   /* 0x48 */  {dissect_unknown, dissect_unknown},
13697   /* 0x49 */  {dissect_unknown, dissect_unknown},
13698   /* 0x4a */  {dissect_unknown, dissect_unknown},
13699   /* 0x4b */  {dissect_unknown, dissect_unknown},
13700   /* 0x4c */  {dissect_unknown, dissect_unknown},
13701   /* 0x4d */  {dissect_unknown, dissect_unknown},
13702   /* 0x4e */  {dissect_unknown, dissect_unknown},
13703   /* 0x4f */  {dissect_unknown, dissect_unknown},
13704
13705   /* 0x50 */  {dissect_unknown, dissect_unknown},
13706   /* 0x51 */  {dissect_unknown, dissect_unknown},
13707   /* 0x52 */  {dissect_unknown, dissect_unknown},
13708   /* 0x53 */  {dissect_unknown, dissect_unknown},
13709   /* 0x54 */  {dissect_unknown, dissect_unknown},
13710   /* 0x55 */  {dissect_unknown, dissect_unknown},
13711   /* 0x56 */  {dissect_unknown, dissect_unknown},
13712   /* 0x57 */  {dissect_unknown, dissect_unknown},
13713   /* 0x58 */  {dissect_unknown, dissect_unknown},
13714   /* 0x59 */  {dissect_unknown, dissect_unknown},
13715   /* 0x5a */  {dissect_unknown, dissect_unknown},
13716   /* 0x5b */  {dissect_unknown, dissect_unknown},
13717   /* 0x5c */  {dissect_unknown, dissect_unknown},
13718   /* 0x5d */  {dissect_unknown, dissect_unknown},
13719   /* 0x5e */  {dissect_unknown, dissect_unknown},
13720   /* 0x5f */  {dissect_unknown, dissect_unknown},
13721
13722   /* 0x60 */  {dissect_unknown, dissect_unknown},
13723   /* 0x61 */  {dissect_unknown, dissect_unknown},
13724   /* 0x62 */  {dissect_unknown, dissect_unknown},
13725   /* 0x63 */  {dissect_unknown, dissect_unknown},
13726   /* 0x64 */  {dissect_unknown, dissect_unknown},
13727   /* 0x65 */  {dissect_unknown, dissect_unknown},
13728   /* 0x66 */  {dissect_unknown, dissect_unknown},
13729   /* 0x67 */  {dissect_unknown, dissect_unknown},
13730   /* 0x68 */  {dissect_unknown, dissect_unknown},
13731   /* 0x69 */  {dissect_unknown, dissect_unknown},
13732   /* 0x6a */  {dissect_unknown, dissect_unknown},
13733   /* 0x6b */  {dissect_unknown, dissect_unknown},
13734   /* 0x6c */  {dissect_unknown, dissect_unknown},
13735   /* 0x6d */  {dissect_unknown, dissect_unknown},
13736   /* 0x6e */  {dissect_unknown, dissect_unknown},
13737   /* 0x6f */  {dissect_unknown, dissect_unknown},
13738
13739   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13740   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13741   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13742   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13743   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13744   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13745   /* 0x76 */  {dissect_unknown, dissect_unknown},
13746   /* 0x77 */  {dissect_unknown, dissect_unknown},
13747   /* 0x78 */  {dissect_unknown, dissect_unknown},
13748   /* 0x79 */  {dissect_unknown, dissect_unknown},
13749   /* 0x7a */  {dissect_unknown, dissect_unknown},
13750   /* 0x7b */  {dissect_unknown, dissect_unknown},
13751   /* 0x7c */  {dissect_unknown, dissect_unknown},
13752   /* 0x7d */  {dissect_unknown, dissect_unknown},
13753   /* 0x7e */  {dissect_unknown, dissect_unknown},
13754   /* 0x7f */  {dissect_unknown, dissect_unknown},
13755
13756   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13757   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13758   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13759   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13760   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13761   /* 0x85 */  {dissect_unknown, dissect_unknown},
13762   /* 0x86 */  {dissect_unknown, dissect_unknown},
13763   /* 0x87 */  {dissect_unknown, dissect_unknown},
13764   /* 0x88 */  {dissect_unknown, dissect_unknown},
13765   /* 0x89 */  {dissect_unknown, dissect_unknown},
13766   /* 0x8a */  {dissect_unknown, dissect_unknown},
13767   /* 0x8b */  {dissect_unknown, dissect_unknown},
13768   /* 0x8c */  {dissect_unknown, dissect_unknown},
13769   /* 0x8d */  {dissect_unknown, dissect_unknown},
13770   /* 0x8e */  {dissect_unknown, dissect_unknown},
13771   /* 0x8f */  {dissect_unknown, dissect_unknown},
13772
13773   /* 0x90 */  {dissect_unknown, dissect_unknown},
13774   /* 0x91 */  {dissect_unknown, dissect_unknown},
13775   /* 0x92 */  {dissect_unknown, dissect_unknown},
13776   /* 0x93 */  {dissect_unknown, dissect_unknown},
13777   /* 0x94 */  {dissect_unknown, dissect_unknown},
13778   /* 0x95 */  {dissect_unknown, dissect_unknown},
13779   /* 0x96 */  {dissect_unknown, dissect_unknown},
13780   /* 0x97 */  {dissect_unknown, dissect_unknown},
13781   /* 0x98 */  {dissect_unknown, dissect_unknown},
13782   /* 0x99 */  {dissect_unknown, dissect_unknown},
13783   /* 0x9a */  {dissect_unknown, dissect_unknown},
13784   /* 0x9b */  {dissect_unknown, dissect_unknown},
13785   /* 0x9c */  {dissect_unknown, dissect_unknown},
13786   /* 0x9d */  {dissect_unknown, dissect_unknown},
13787   /* 0x9e */  {dissect_unknown, dissect_unknown},
13788   /* 0x9f */  {dissect_unknown, dissect_unknown},
13789
13790   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13791   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13792   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13793   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13794   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13795   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13796   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13797   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13798   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13799   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13800   /* 0xaa */  {dissect_unknown, dissect_unknown},
13801   /* 0xab */  {dissect_unknown, dissect_unknown},
13802   /* 0xac */  {dissect_unknown, dissect_unknown},
13803   /* 0xad */  {dissect_unknown, dissect_unknown},
13804   /* 0xae */  {dissect_unknown, dissect_unknown},
13805   /* 0xaf */  {dissect_unknown, dissect_unknown},
13806
13807   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13808   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13809   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13810   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13811   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13812   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13813   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13814   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13815   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13816   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13817   /* 0xba */  {dissect_unknown, dissect_unknown},
13818   /* 0xbb */  {dissect_unknown, dissect_unknown},
13819   /* 0xbc */  {dissect_unknown, dissect_unknown},
13820   /* 0xbd */  {dissect_unknown, dissect_unknown},
13821   /* 0xbe */  {dissect_unknown, dissect_unknown},
13822   /* 0xbf */  {dissect_unknown, dissect_unknown},
13823
13824   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13825   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13826   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13827   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13828   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13829   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13830   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13831   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13832   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13833   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13834   /* 0xca */  {dissect_unknown, dissect_unknown},
13835   /* 0xcb */  {dissect_unknown, dissect_unknown},
13836   /* 0xcc */  {dissect_unknown, dissect_unknown},
13837   /* 0xcd */  {dissect_unknown, dissect_unknown},
13838   /* 0xce */  {dissect_unknown, dissect_unknown},
13839   /* 0xcf */  {dissect_unknown, dissect_unknown},
13840
13841   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13842   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13843   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13844   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13845   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13846   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13847   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13848   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13849   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13850   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13851   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13852   /* 0xdb */  {dissect_unknown, dissect_unknown},
13853   /* 0xdc */  {dissect_unknown, dissect_unknown},
13854   /* 0xdd */  {dissect_unknown, dissect_unknown},
13855   /* 0xde */  {dissect_unknown, dissect_unknown},
13856   /* 0xdf */  {dissect_unknown, dissect_unknown},
13857
13858   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13859   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13860   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13861   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13862   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13863   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13864   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13865   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13866   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13867   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13868   /* 0xea */  {dissect_unknown, dissect_unknown},
13869   /* 0xeb */  {dissect_unknown, dissect_unknown},
13870   /* 0xec */  {dissect_unknown, dissect_unknown},
13871   /* 0xed */  {dissect_unknown, dissect_unknown},
13872   /* 0xee */  {dissect_unknown, dissect_unknown},
13873   /* 0xef */  {dissect_unknown, dissect_unknown},
13874
13875   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13876   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13877   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13878   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13879   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13880   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13881   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13882   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13883   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13884   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13885   /* 0xfa */  {dissect_unknown, dissect_unknown},
13886   /* 0xfb */  {dissect_unknown, dissect_unknown},
13887   /* 0xfc */  {dissect_unknown, dissect_unknown},
13888   /* 0xfd */  {dissect_unknown, dissect_unknown},
13889   /* 0xfe */  {dissect_unknown, dissect_unknown},
13890   /* 0xff */  {dissect_unknown, dissect_unknown},
13891 };
13892
13893 static int
13894 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
13895 {
13896         smb_info_t *si;
13897
13898         si = pinfo->private_data;
13899         if(cmd!=0xff){
13900                 proto_item *cmd_item;
13901                 proto_tree *cmd_tree;
13902                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13903
13904                 if (check_col(pinfo->cinfo, COL_INFO)) {
13905                         if(first_pdu){
13906                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13907                                         "%s %s",
13908                                         decode_smb_name(cmd),
13909                                         (si->request)? "Request" : "Response");
13910                         } else {
13911                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13912                                         "; %s",
13913                                         decode_smb_name(cmd));
13914                         }
13915
13916                 }
13917
13918                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13919                         "%s %s (0x%02x)",
13920                         decode_smb_name(cmd),
13921                         (si->request)?"Request":"Response",
13922                         cmd);
13923
13924                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13925
13926                 dissector = (si->request)?
13927                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13928
13929                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13930                 proto_item_set_end(cmd_item, tvb, offset);
13931         }
13932         return offset;
13933 }
13934
13935
13936 /* NOTE: this value_string array will also be used to access data directly by
13937  * index instead of val_to_str() since
13938  * 1, the array will always span every value from 0x00 to 0xff and
13939  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13940  * This means that this value_string array MUST always
13941  * 1, contain all entries 0x00 to 0xff
13942  * 2, all entries must be in order.
13943  */
13944 const value_string smb_cmd_vals[] = {
13945   { 0x00, "Create Directory" },
13946   { 0x01, "Delete Directory" },
13947   { 0x02, "Open" },
13948   { 0x03, "Create" },
13949   { 0x04, "Close" },
13950   { 0x05, "Flush" },
13951   { 0x06, "Delete" },
13952   { 0x07, "Rename" },
13953   { 0x08, "Query Information" },
13954   { 0x09, "Set Information" },
13955   { 0x0A, "Read" },
13956   { 0x0B, "Write" },
13957   { 0x0C, "Lock Byte Range" },
13958   { 0x0D, "Unlock Byte Range" },
13959   { 0x0E, "Create Temp" },
13960   { 0x0F, "Create New" },
13961   { 0x10, "Check Directory" },
13962   { 0x11, "Process Exit" },
13963   { 0x12, "Seek" },
13964   { 0x13, "Lock And Read" },
13965   { 0x14, "Write And Unlock" },
13966   { 0x15, "unknown-0x15" },
13967   { 0x16, "unknown-0x16" },
13968   { 0x17, "unknown-0x17" },
13969   { 0x18, "unknown-0x18" },
13970   { 0x19, "unknown-0x19" },
13971   { 0x1A, "Read Raw" },
13972   { 0x1B, "Read MPX" },
13973   { 0x1C, "Read MPX Secondary" },
13974   { 0x1D, "Write Raw" },
13975   { 0x1E, "Write MPX" },
13976   { 0x1F, "Write MPX Secondary" },
13977   { 0x20, "Write Complete" },
13978   { 0x21, "unknown-0x21" },
13979   { 0x22, "Set Information2" },
13980   { 0x23, "Query Information2" },
13981   { 0x24, "Locking AndX" },
13982   { 0x25, "Trans" },
13983   { 0x26, "Trans Secondary" },
13984   { 0x27, "IOCTL" },
13985   { 0x28, "IOCTL Secondary" },
13986   { 0x29, "Copy" },
13987   { 0x2A, "Move" },
13988   { 0x2B, "Echo" },
13989   { 0x2C, "Write And Close" },
13990   { 0x2D, "Open AndX" },
13991   { 0x2E, "Read AndX" },
13992   { 0x2F, "Write AndX" },
13993   { 0x30, "unknown-0x30" },
13994   { 0x31, "Close And Tree Disconnect" },
13995   { 0x32, "Trans2" },
13996   { 0x33, "Trans2 Secondary" },
13997   { 0x34, "Find Close2" },
13998   { 0x35, "Find Notify Close" },
13999   { 0x36, "unknown-0x36" },
14000   { 0x37, "unknown-0x37" },
14001   { 0x38, "unknown-0x38" },
14002   { 0x39, "unknown-0x39" },
14003   { 0x3A, "unknown-0x3A" },
14004   { 0x3B, "unknown-0x3B" },
14005   { 0x3C, "unknown-0x3C" },
14006   { 0x3D, "unknown-0x3D" },
14007   { 0x3E, "unknown-0x3E" },
14008   { 0x3F, "unknown-0x3F" },
14009   { 0x40, "unknown-0x40" },
14010   { 0x41, "unknown-0x41" },
14011   { 0x42, "unknown-0x42" },
14012   { 0x43, "unknown-0x43" },
14013   { 0x44, "unknown-0x44" },
14014   { 0x45, "unknown-0x45" },
14015   { 0x46, "unknown-0x46" },
14016   { 0x47, "unknown-0x47" },
14017   { 0x48, "unknown-0x48" },
14018   { 0x49, "unknown-0x49" },
14019   { 0x4A, "unknown-0x4A" },
14020   { 0x4B, "unknown-0x4B" },
14021   { 0x4C, "unknown-0x4C" },
14022   { 0x4D, "unknown-0x4D" },
14023   { 0x4E, "unknown-0x4E" },
14024   { 0x4F, "unknown-0x4F" },
14025   { 0x50, "unknown-0x50" },
14026   { 0x51, "unknown-0x51" },
14027   { 0x52, "unknown-0x52" },
14028   { 0x53, "unknown-0x53" },
14029   { 0x54, "unknown-0x54" },
14030   { 0x55, "unknown-0x55" },
14031   { 0x56, "unknown-0x56" },
14032   { 0x57, "unknown-0x57" },
14033   { 0x58, "unknown-0x58" },
14034   { 0x59, "unknown-0x59" },
14035   { 0x5A, "unknown-0x5A" },
14036   { 0x5B, "unknown-0x5B" },
14037   { 0x5C, "unknown-0x5C" },
14038   { 0x5D, "unknown-0x5D" },
14039   { 0x5E, "unknown-0x5E" },
14040   { 0x5F, "unknown-0x5F" },
14041   { 0x60, "unknown-0x60" },
14042   { 0x61, "unknown-0x61" },
14043   { 0x62, "unknown-0x62" },
14044   { 0x63, "unknown-0x63" },
14045   { 0x64, "unknown-0x64" },
14046   { 0x65, "unknown-0x65" },
14047   { 0x66, "unknown-0x66" },
14048   { 0x67, "unknown-0x67" },
14049   { 0x68, "unknown-0x68" },
14050   { 0x69, "unknown-0x69" },
14051   { 0x6A, "unknown-0x6A" },
14052   { 0x6B, "unknown-0x6B" },
14053   { 0x6C, "unknown-0x6C" },
14054   { 0x6D, "unknown-0x6D" },
14055   { 0x6E, "unknown-0x6E" },
14056   { 0x6F, "unknown-0x6F" },
14057   { 0x70, "Tree Connect" },
14058   { 0x71, "Tree Disconnect" },
14059   { 0x72, "Negotiate Protocol" },
14060   { 0x73, "Session Setup AndX" },
14061   { 0x74, "Logoff AndX" },
14062   { 0x75, "Tree Connect AndX" },
14063   { 0x76, "unknown-0x76" },
14064   { 0x77, "unknown-0x77" },
14065   { 0x78, "unknown-0x78" },
14066   { 0x79, "unknown-0x79" },
14067   { 0x7A, "unknown-0x7A" },
14068   { 0x7B, "unknown-0x7B" },
14069   { 0x7C, "unknown-0x7C" },
14070   { 0x7D, "unknown-0x7D" },
14071   { 0x7E, "unknown-0x7E" },
14072   { 0x7F, "unknown-0x7F" },
14073   { 0x80, "Query Information Disk" },
14074   { 0x81, "Search" },
14075   { 0x82, "Find" },
14076   { 0x83, "Find Unique" },
14077   { 0x84, "Find Close" },
14078   { 0x85, "unknown-0x85" },
14079   { 0x86, "unknown-0x86" },
14080   { 0x87, "unknown-0x87" },
14081   { 0x88, "unknown-0x88" },
14082   { 0x89, "unknown-0x89" },
14083   { 0x8A, "unknown-0x8A" },
14084   { 0x8B, "unknown-0x8B" },
14085   { 0x8C, "unknown-0x8C" },
14086   { 0x8D, "unknown-0x8D" },
14087   { 0x8E, "unknown-0x8E" },
14088   { 0x8F, "unknown-0x8F" },
14089   { 0x90, "unknown-0x90" },
14090   { 0x91, "unknown-0x91" },
14091   { 0x92, "unknown-0x92" },
14092   { 0x93, "unknown-0x93" },
14093   { 0x94, "unknown-0x94" },
14094   { 0x95, "unknown-0x95" },
14095   { 0x96, "unknown-0x96" },
14096   { 0x97, "unknown-0x97" },
14097   { 0x98, "unknown-0x98" },
14098   { 0x99, "unknown-0x99" },
14099   { 0x9A, "unknown-0x9A" },
14100   { 0x9B, "unknown-0x9B" },
14101   { 0x9C, "unknown-0x9C" },
14102   { 0x9D, "unknown-0x9D" },
14103   { 0x9E, "unknown-0x9E" },
14104   { 0x9F, "unknown-0x9F" },
14105   { 0xA0, "NT Trans" },
14106   { 0xA1, "NT Trans Secondary" },
14107   { 0xA2, "NT Create AndX" },
14108   { 0xA3, "unknown-0xA3" },
14109   { 0xA4, "NT Cancel" },
14110   { 0xA5, "NT Rename" },
14111   { 0xA6, "unknown-0xA6" },
14112   { 0xA7, "unknown-0xA7" },
14113   { 0xA8, "unknown-0xA8" },
14114   { 0xA9, "unknown-0xA9" },
14115   { 0xAA, "unknown-0xAA" },
14116   { 0xAB, "unknown-0xAB" },
14117   { 0xAC, "unknown-0xAC" },
14118   { 0xAD, "unknown-0xAD" },
14119   { 0xAE, "unknown-0xAE" },
14120   { 0xAF, "unknown-0xAF" },
14121   { 0xB0, "unknown-0xB0" },
14122   { 0xB1, "unknown-0xB1" },
14123   { 0xB2, "unknown-0xB2" },
14124   { 0xB3, "unknown-0xB3" },
14125   { 0xB4, "unknown-0xB4" },
14126   { 0xB5, "unknown-0xB5" },
14127   { 0xB6, "unknown-0xB6" },
14128   { 0xB7, "unknown-0xB7" },
14129   { 0xB8, "unknown-0xB8" },
14130   { 0xB9, "unknown-0xB9" },
14131   { 0xBA, "unknown-0xBA" },
14132   { 0xBB, "unknown-0xBB" },
14133   { 0xBC, "unknown-0xBC" },
14134   { 0xBD, "unknown-0xBD" },
14135   { 0xBE, "unknown-0xBE" },
14136   { 0xBF, "unknown-0xBF" },
14137   { 0xC0, "Open Print File" },
14138   { 0xC1, "Write Print File" },
14139   { 0xC2, "Close Print File" },
14140   { 0xC3, "Get Print Queue" },
14141   { 0xC4, "unknown-0xC4" },
14142   { 0xC5, "unknown-0xC5" },
14143   { 0xC6, "unknown-0xC6" },
14144   { 0xC7, "unknown-0xC7" },
14145   { 0xC8, "unknown-0xC8" },
14146   { 0xC9, "unknown-0xC9" },
14147   { 0xCA, "unknown-0xCA" },
14148   { 0xCB, "unknown-0xCB" },
14149   { 0xCC, "unknown-0xCC" },
14150   { 0xCD, "unknown-0xCD" },
14151   { 0xCE, "unknown-0xCE" },
14152   { 0xCF, "unknown-0xCF" },
14153   { 0xD0, "Send Single Block Message" },
14154   { 0xD1, "Send Broadcast Message" },
14155   { 0xD2, "Forward User Name" },
14156   { 0xD3, "Cancel Forward" },
14157   { 0xD4, "Get Machine Name" },
14158   { 0xD5, "Send Start of Multi-block Message" },
14159   { 0xD6, "Send End of Multi-block Message" },
14160   { 0xD7, "Send Text of Multi-block Message" },
14161   { 0xD8, "SMBreadbulk" },
14162   { 0xD9, "SMBwritebulk" },
14163   { 0xDA, "SMBwritebulkdata" },
14164   { 0xDB, "unknown-0xDB" },
14165   { 0xDC, "unknown-0xDC" },
14166   { 0xDD, "unknown-0xDD" },
14167   { 0xDE, "unknown-0xDE" },
14168   { 0xDF, "unknown-0xDF" },
14169   { 0xE0, "unknown-0xE0" },
14170   { 0xE1, "unknown-0xE1" },
14171   { 0xE2, "unknown-0xE2" },
14172   { 0xE3, "unknown-0xE3" },
14173   { 0xE4, "unknown-0xE4" },
14174   { 0xE5, "unknown-0xE5" },
14175   { 0xE6, "unknown-0xE6" },
14176   { 0xE7, "unknown-0xE7" },
14177   { 0xE8, "unknown-0xE8" },
14178   { 0xE9, "unknown-0xE9" },
14179   { 0xEA, "unknown-0xEA" },
14180   { 0xEB, "unknown-0xEB" },
14181   { 0xEC, "unknown-0xEC" },
14182   { 0xED, "unknown-0xED" },
14183   { 0xEE, "unknown-0xEE" },
14184   { 0xEF, "unknown-0xEF" },
14185   { 0xF0, "unknown-0xF0" },
14186   { 0xF1, "unknown-0xF1" },
14187   { 0xF2, "unknown-0xF2" },
14188   { 0xF3, "unknown-0xF3" },
14189   { 0xF4, "unknown-0xF4" },
14190   { 0xF5, "unknown-0xF5" },
14191   { 0xF6, "unknown-0xF6" },
14192   { 0xF7, "unknown-0xF7" },
14193   { 0xF8, "unknown-0xF8" },
14194   { 0xF9, "unknown-0xF9" },
14195   { 0xFA, "unknown-0xFA" },
14196   { 0xFB, "unknown-0xFB" },
14197   { 0xFC, "unknown-0xFC" },
14198   { 0xFD, "unknown-0xFD" },
14199   { 0xFE, "SMBinvalid" },
14200   { 0xFF, "unknown-0xFF" },
14201   { 0x00, NULL },
14202 };
14203
14204 static char *decode_smb_name(guint8 cmd)
14205 {
14206   return(smb_cmd_vals[cmd].strptr);
14207 }
14208
14209
14210
14211 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14212  * Everything TVBUFFIFIED above this line
14213  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14214
14215
14216 static void
14217 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14218 {
14219         conv_tables_t *ct = ctarg;
14220
14221         if (ct->unmatched)
14222                 g_hash_table_destroy(ct->unmatched);
14223         if (ct->matched)
14224                 g_hash_table_destroy(ct->matched);
14225         if (ct->tid_service)
14226                 g_hash_table_destroy(ct->tid_service);
14227 }
14228
14229 static void
14230 smb_init_protocol(void)
14231 {
14232         if (smb_saved_info_key_chunk)
14233                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14234         if (smb_saved_info_chunk)
14235                 g_mem_chunk_destroy(smb_saved_info_chunk);
14236         if (smb_nt_transact_info_chunk)
14237                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14238         if (smb_transact2_info_chunk)
14239                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14240         if (smb_transact_info_chunk)
14241                 g_mem_chunk_destroy(smb_transact_info_chunk);
14242
14243         /*
14244          * Free the hash tables attached to the conversation table
14245          * structures, and then free the list of conversation table
14246          * data structures (which doesn't free the data structures
14247          * themselves; that's done by destroying the chunk from
14248          * which they were allocated).
14249          */
14250         if (conv_tables) {
14251                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14252                 g_slist_free(conv_tables);
14253                 conv_tables = NULL;
14254         }
14255
14256         /*
14257          * Now destroy the chunk from which the conversation table
14258          * structures were allocated.
14259          */
14260         if (conv_tables_chunk)
14261                 g_mem_chunk_destroy(conv_tables_chunk);
14262
14263         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14264             sizeof(smb_saved_info_t),
14265             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14266             G_ALLOC_ONLY);
14267         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14268             sizeof(smb_saved_info_key_t),
14269             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14270             G_ALLOC_ONLY);
14271         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14272             sizeof(smb_nt_transact_info_t),
14273             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14274             G_ALLOC_ONLY);
14275         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14276             sizeof(smb_transact2_info_t),
14277             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14278             G_ALLOC_ONLY);
14279         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14280             sizeof(smb_transact_info_t),
14281             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14282             G_ALLOC_ONLY);
14283         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14284             sizeof(conv_tables_t),
14285             conv_tables_count * sizeof(conv_tables_t),
14286             G_ALLOC_ONLY);
14287 }
14288
14289 static const value_string errcls_types[] = {
14290   { SMB_SUCCESS, "Success"},
14291   { SMB_ERRDOS, "DOS Error"},
14292   { SMB_ERRSRV, "Server Error"},
14293   { SMB_ERRHRD, "Hardware Error"},
14294   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14295   { 0, NULL }
14296 };
14297
14298 /* Error codes for the ERRSRV class */
14299
14300 static const value_string SRV_errors[] = {
14301   {SMBE_error, "Non specific error code"},
14302   {SMBE_badpw, "Bad password"},
14303   {SMBE_badtype, "Reserved"},
14304   {SMBE_access, "No permissions to perform the requested operation"},
14305   {SMBE_invnid, "TID invalid"},
14306   {SMBE_invnetname, "Invalid network name. Service not found"},
14307   {SMBE_invdevice, "Invalid device"},
14308   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14309   {SMBE_qfull, "Print queue full"},
14310   {SMBE_qtoobig, "Queued item too big"},
14311   {SMBE_qeof, "EOF on print queue dump"},
14312   {SMBE_invpfid, "Invalid print file in smb_fid"},
14313   {SMBE_smbcmd, "Unrecognised command"},
14314   {SMBE_srverror, "SMB server internal error"},
14315   {SMBE_filespecs, "Fid and pathname invalid combination"},
14316   {SMBE_badlink, "Bad link in request ???"},
14317   {SMBE_badpermits, "Access specified for a file is not valid"},
14318   {SMBE_badpid, "Bad process id in request"},
14319   {SMBE_setattrmode, "Attribute mode invalid"},
14320   {SMBE_paused, "Message server paused"},
14321   {SMBE_msgoff, "Not receiving messages"},
14322   {SMBE_noroom, "No room for message"},
14323   {SMBE_rmuns, "Too many remote usernames"},
14324   {SMBE_timeout, "Operation timed out"},
14325   {SMBE_noresource, "No resources currently available for request."},
14326   {SMBE_toomanyuids, "Too many userids"},
14327   {SMBE_baduid, "Bad userid"},
14328   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14329   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14330   {SMBE_contMPX, "Resume MPX mode"},
14331   {SMBE_badPW, "Bad Password???"},
14332   {SMBE_nosupport, "Operation not supported"},
14333   { 0, NULL}
14334 };
14335
14336 /* Error codes for the ERRHRD class */
14337
14338 static const value_string HRD_errors[] = {
14339   {SMBE_nowrite, "Read only media"},
14340   {SMBE_badunit, "Unknown device"},
14341   {SMBE_notready, "Drive not ready"},
14342   {SMBE_badcmd, "Unknown command"},
14343   {SMBE_data, "Data (CRC) error"},
14344   {SMBE_badreq, "Bad request structure length"},
14345   {SMBE_seek, "Seek error"},
14346   {SMBE_badmedia, "Unknown media type"},
14347   {SMBE_badsector, "Sector not found"},
14348   {SMBE_nopaper, "Printer out of paper"},
14349   {SMBE_write, "Write fault"},
14350   {SMBE_read, "Read fault"},
14351   {SMBE_general, "General failure"},
14352   {SMBE_badshare, "A open conflicts with an existing open"},
14353   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14354   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14355   {SMBE_FCBunavail, "No FCBs are available to process request"},
14356   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14357   {SMBE_diskfull, "Disk full???"},
14358   {0, NULL}
14359 };
14360
14361 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14362 {
14363
14364   switch (errcls) {
14365
14366   case SMB_SUCCESS:
14367
14368     return("No Error");   /* No error ??? */
14369     break;
14370
14371   case SMB_ERRDOS:
14372
14373     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14374     break;
14375
14376   case SMB_ERRSRV:
14377
14378     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14379     break;
14380
14381   case SMB_ERRHRD:
14382
14383     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14384     break;
14385
14386   default:
14387
14388     return("Unknown error class!");
14389
14390   }
14391
14392 }
14393
14394 static const true_false_string tfs_smb_flags_lock = {
14395         "Lock&Read, Write&Unlock are supported",
14396         "Lock&Read, Write&Unlock are not supported"
14397 };
14398 static const true_false_string tfs_smb_flags_receive_buffer = {
14399         "Receive buffer has been posted",
14400         "Receive buffer has not been posted"
14401 };
14402 static const true_false_string tfs_smb_flags_caseless = {
14403         "Path names are caseless",
14404         "Path names are case sensitive"
14405 };
14406 static const true_false_string tfs_smb_flags_canon = {
14407         "Pathnames are canonicalized",
14408         "Pathnames are not canonicalized"
14409 };
14410 static const true_false_string tfs_smb_flags_oplock = {
14411         "OpLock requested/granted",
14412         "OpLock not requested/granted"
14413 };
14414 static const true_false_string tfs_smb_flags_notify = {
14415         "Notify client on all modifications",
14416         "Notify client only on open"
14417 };
14418 static const true_false_string tfs_smb_flags_response = {
14419         "Message is a response to the client/redirector",
14420         "Message is a request to the server"
14421 };
14422
14423 static int
14424 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14425 {
14426         guint8 mask;
14427         proto_item *item = NULL;
14428         proto_tree *tree = NULL;
14429
14430         mask = tvb_get_guint8(tvb, offset);
14431
14432         if(parent_tree){
14433                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
14434                         "Flags: 0x%02x", mask);
14435                 tree = proto_item_add_subtree(item, ett_smb_flags);
14436         }
14437         proto_tree_add_boolean(tree, hf_smb_flags_response,
14438                 tvb, offset, 1, mask);
14439         proto_tree_add_boolean(tree, hf_smb_flags_notify,
14440                 tvb, offset, 1, mask);
14441         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
14442                 tvb, offset, 1, mask);
14443         proto_tree_add_boolean(tree, hf_smb_flags_canon,
14444                 tvb, offset, 1, mask);
14445         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
14446                 tvb, offset, 1, mask);
14447         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
14448                 tvb, offset, 1, mask);
14449         proto_tree_add_boolean(tree, hf_smb_flags_lock,
14450                 tvb, offset, 1, mask);
14451         offset += 1;
14452         return offset;
14453 }
14454
14455
14456
14457 static const true_false_string tfs_smb_flags2_long_names_allowed = {
14458         "Long file names are allowed in the response",
14459         "Long file names are not allowed in the response"
14460 };
14461 static const true_false_string tfs_smb_flags2_ea = {
14462         "Extended attributes are supported",
14463         "Extended attributes are not supported"
14464 };
14465 static const true_false_string tfs_smb_flags2_sec_sig = {
14466         "Security signatures are supported",
14467         "Security signatures are not supported"
14468 };
14469 static const true_false_string tfs_smb_flags2_long_names_used = {
14470         "Path names in request are long file names",
14471         "Path names in request are not long file names"
14472 };
14473 static const true_false_string tfs_smb_flags2_esn = {
14474         "Extended security negotiation is supported",
14475         "Extended security negotiation is not supported"
14476 };
14477 static const true_false_string tfs_smb_flags2_dfs = {
14478         "Resolve pathnames with Dfs",
14479         "Don't resolve pathnames with Dfs"
14480 };
14481 static const true_false_string tfs_smb_flags2_roe = {
14482         "Permit reads if execute-only",
14483         "Don't permit reads if execute-only"
14484 };
14485 static const true_false_string tfs_smb_flags2_nt_error = {
14486         "Error codes are NT error codes",
14487         "Error codes are DOS error codes"
14488 };
14489 static const true_false_string tfs_smb_flags2_string = {
14490         "Strings are Unicode",
14491         "Strings are ASCII"
14492 };
14493 static int
14494 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14495 {
14496         guint16 mask;
14497         proto_item *item = NULL;
14498         proto_tree *tree = NULL;
14499
14500         mask = tvb_get_letohs(tvb, offset);
14501
14502         if(parent_tree){
14503                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
14504                         "Flags2: 0x%04x", mask);
14505                 tree = proto_item_add_subtree(item, ett_smb_flags2);
14506         }
14507
14508         proto_tree_add_boolean(tree, hf_smb_flags2_string,
14509                 tvb, offset, 2, mask);
14510         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
14511                 tvb, offset, 2, mask);
14512         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
14513                 tvb, offset, 2, mask);
14514         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
14515                 tvb, offset, 2, mask);
14516         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
14517                 tvb, offset, 2, mask);
14518         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
14519                 tvb, offset, 2, mask);
14520         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
14521                 tvb, offset, 2, mask);
14522         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
14523                 tvb, offset, 2, mask);
14524         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
14525                 tvb, offset, 2, mask);
14526
14527         offset += 2;
14528         return offset;
14529 }
14530
14531
14532
14533 #define SMB_FLAGS_DIRN 0x80
14534
14535
14536 static void
14537 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14538 {
14539         int offset = 0;
14540         proto_item *item = NULL, *hitem = NULL;
14541         proto_tree *tree = NULL, *htree = NULL;
14542         guint8          flags;
14543         guint16         flags2;
14544         static smb_info_t       si_arr[20];
14545         static int si_counter=0;
14546         smb_info_t              *si;
14547         smb_saved_info_t *sip = NULL;
14548         smb_saved_info_key_t key;
14549         smb_saved_info_key_t *new_key;
14550         guint32 nt_status = 0;
14551         guint8 errclass = 0;
14552         guint16 errcode = 0;
14553         guint32 pid_mid;
14554         conversation_t *conversation;
14555         nstime_t ns;
14556
14557         si_counter++;
14558         if(si_counter==20){
14559                 si_counter=0;
14560         }
14561         si=&si_arr[si_counter];
14562
14563         top_tree=parent_tree;
14564
14565         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
14566                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
14567         }
14568         if (check_col(pinfo->cinfo, COL_INFO)){
14569                 col_clear(pinfo->cinfo, COL_INFO);
14570         }
14571
14572         /* start off using the local variable, we will allocate a new one if we
14573            need to*/
14574         si->cmd = tvb_get_guint8(tvb, offset+4);
14575         flags = tvb_get_guint8(tvb, offset+9);
14576         /*
14577          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
14578          * the direction flag appears never to be set, even for what appear
14579          * to be replies.  Do some SMB servers fail to set that flag,
14580          * under the assumption that the client knows it's a reply because
14581          * it received it?
14582          */
14583         si->request = !(flags&SMB_FLAGS_DIRN);
14584         flags2 = tvb_get_letohs(tvb, offset+10);
14585         if(flags2 & 0x8000){
14586                 si->unicode = TRUE; /* Mark them as Unicode */
14587         } else {
14588                 si->unicode = FALSE;
14589         }
14590         si->tid = tvb_get_letohs(tvb, offset+24);
14591         si->pid = tvb_get_letohs(tvb, offset+26);
14592         si->uid = tvb_get_letohs(tvb, offset+28);
14593         si->mid = tvb_get_letohs(tvb, offset+30);
14594         pid_mid = (si->pid << 16) | si->mid;
14595         si->info_level = -1;
14596         si->info_count = -1;
14597
14598         if (parent_tree) {
14599                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
14600                         -1, FALSE);
14601                 tree = proto_item_add_subtree(item, ett_smb);
14602
14603                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
14604                         "SMB Header");
14605
14606                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
14607         }
14608
14609         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
14610         offset += 4;  /* Skip the marker */
14611
14612         /* find which conversation we are part of and get the tables for that
14613            conversation*/
14614         conversation = find_conversation(&pinfo->src, &pinfo->dst,
14615                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
14616         if(!conversation){
14617                 /* OK this is a new conversation so lets create it */
14618                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
14619                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
14620         }
14621         /* see if we already have the smb data for this conversation */
14622         si->ct=conversation_get_proto_data(conversation, proto_smb);
14623         if(!si->ct){
14624                 /* No, not yet. create it and attach it to the conversation */
14625                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
14626                 conv_tables = g_slist_prepend(conv_tables, si->ct);
14627                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
14628                         smb_saved_info_equal_matched);
14629                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
14630                         smb_saved_info_equal_unmatched);
14631                 si->ct->tid_service=g_hash_table_new(
14632                         smb_saved_info_hash_unmatched,
14633                         smb_saved_info_equal_unmatched);
14634                 conversation_add_proto_data(conversation, proto_smb, si->ct);
14635         }
14636
14637         if( (si->request)
14638             &&  (si->mid==0)
14639             &&  (si->uid==0)
14640             &&  (si->pid==0)
14641             &&  (si->tid==0) ){
14642                 /* this is a broadcast SMB packet, there will not be a reply.
14643                    We dont need to do anything
14644                 */
14645                 si->unidir = TRUE;
14646         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
14647                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
14648                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
14649                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
14650                 /* Ok, we got a special request type. This request is either
14651                    an NT Cancel or a continuation relative to a real request
14652                    in an earlier packet.  In either case, we don't expect any
14653                    responses to this packet.  For continuations, any later
14654                    responses we see really just belong to the original request.
14655                    Anyway, we want to remember this packet somehow and
14656                    remember which original request it is associated with so
14657                    we can say nice things such as "This is a Cancellation to
14658                    the request in frame x", but we don't want the
14659                    request/response matching to get messed up.
14660
14661                    The only thing we do in this case is trying to find which original
14662                    request we match with and insert an entry for this "special"
14663                    request for later reference. We continue to reference the original
14664                    requests smb_saved_info_t but we dont touch it or change anything
14665                    in it.
14666                 */
14667
14668                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
14669
14670                 if(!pinfo->fd->flags.visited){
14671                         /* try to find which original call we match and if we
14672                            find it add us to the matched table. Dont touch
14673                            anything else since we dont want this one to mess
14674                            up the request/response matching. We still consider
14675                            the initial call the real request and this is only
14676                            some sort of continuation.
14677                         */
14678                         /* we only check the unmatched table and assume that the
14679                            last seen MID matching ours is the right one.
14680                            This can fail but is better than nothing
14681                         */
14682                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
14683                         if(sip!=NULL){
14684                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14685                                 new_key->frame = pinfo->fd->num;
14686                                 new_key->pid_mid = pid_mid;
14687                                 g_hash_table_insert(si->ct->matched, new_key,
14688                                     sip);
14689                         }
14690                 } else {
14691                         /* we have seen this packet before; check the
14692                            matching table
14693                         */
14694                         key.frame = pinfo->fd->num;
14695                         key.pid_mid = pid_mid;
14696                         sip=g_hash_table_lookup(si->ct->matched, &key);
14697                         if(sip==NULL){
14698                         /*
14699                           We didn't find it.
14700                           Too bad, unfortunately there is not really much we can
14701                           do now since this means that we never saw the initial
14702                           request.
14703                          */
14704                         }
14705                 }
14706
14707
14708                 if(sip && sip->frame_req){
14709                         switch(si->cmd){
14710                         case SMB_COM_NT_CANCEL:
14711                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
14712                                                     tvb, 0, 0, sip->frame_req);
14713                                 break;
14714                         case SMB_COM_TRANSACTION_SECONDARY:
14715                         case SMB_COM_TRANSACTION2_SECONDARY:
14716                         case SMB_COM_NT_TRANSACT_SECONDARY:
14717                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
14718                                                     tvb, 0, 0, sip->frame_req);
14719                                 break;
14720                         }
14721                 } else {
14722                         switch(si->cmd){
14723                         case SMB_COM_NT_CANCEL:
14724                                 proto_tree_add_text(htree, tvb, 0, 0,
14725                                                     "Cancellation to: <unknown frame>");
14726                                 break;
14727                         case SMB_COM_TRANSACTION_SECONDARY:
14728                         case SMB_COM_TRANSACTION2_SECONDARY:
14729                         case SMB_COM_NT_TRANSACT_SECONDARY:
14730                                 proto_tree_add_text(htree, tvb, 0, 0,
14731                                                     "Continuation to: <unknown frame>");
14732                                 break;
14733                         }
14734                 }
14735         } else { /* normal bidirectional request or response */
14736                 si->unidir = FALSE;
14737
14738                 if(!pinfo->fd->flags.visited){
14739                         /* first see if we find an unmatched smb "equal" to
14740                            the current one
14741                         */
14742                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
14743                         if(sip!=NULL){
14744                                 gboolean cmd_match=FALSE;
14745
14746                                 /*
14747                                  * Make sure the SMB we found was the
14748                                  * same command, or a different command
14749                                  * that's another valid type of reply
14750                                  * to that command.
14751                                  */
14752                                 if(si->cmd==sip->cmd){
14753                                         cmd_match=TRUE;
14754                                 }
14755                                 else if(si->cmd==SMB_COM_NT_CANCEL){
14756                                         cmd_match=TRUE;
14757                                 }
14758                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
14759                                      && (sip->cmd==SMB_COM_TRANSACTION)){
14760                                         cmd_match=TRUE;
14761                                 }
14762                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
14763                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
14764                                         cmd_match=TRUE;
14765                                 }
14766                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
14767                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
14768                                         cmd_match=TRUE;
14769                                 }
14770
14771                                 if( (si->request) || (!cmd_match) ) {
14772                                         /* If we are processing an SMB request but there was already
14773                                            another "identical" smb resuest we had not matched yet.
14774                                            This must mean that either we have a retransmission or that the
14775                                            response to the previous one was lost and the client has reused
14776                                            the MID for this conversation. In either case it's not much more
14777                                            we can do than forget the old request and concentrate on the
14778                                            present one instead.
14779
14780                                            We also do this cleanup if we see that the cmd in the original
14781                                            request in sip->cmd is not compatible with the current cmd.
14782                                            This is to prevent matching errors such as if there were two
14783                                            SMBs of different cmds but with identical MID and PID values and
14784                                            if ethereal lost the first reply and the second request.
14785                                         */
14786                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
14787                                         sip=NULL; /* XXX should free it as well */
14788                                 } else {
14789                                         /* we have found a response to some request we have seen earlier.
14790                                            What we do now depends on whether this is the first response
14791                                            to that request we see (id frame_res==0) or not.
14792                                         */
14793                                         if(sip->frame_res==0){
14794                                                 /* ok it is the first response we have seen to this packet */
14795                                                 sip->frame_res = pinfo->fd->num;
14796                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14797                                                 new_key->frame = sip->frame_res;
14798                                                 new_key->pid_mid = pid_mid;
14799                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
14800                                         } else {
14801                                                 /* We have already seen another response to this MID.
14802                                                    Since the MID in reality is only something like 10 bits
14803                                                    this probably means that we just have a MID that is being
14804                                                    reused due to the small MID space and that this is a new
14805                                                    command we did not see the original request for.
14806                                                 */
14807                                                 sip=NULL;
14808                                         }
14809                                 }
14810                         }
14811                         if(si->request){
14812                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
14813                                 sip->frame_req = pinfo->fd->num;
14814                                 sip->frame_res = 0;
14815                                 sip->req_time.secs=pinfo->fd->abs_secs;
14816                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
14817                                 sip->flags = 0;
14818                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
14819                                     == (void *)TID_IPC) {
14820                                         sip->flags |= SMB_SIF_TID_IS_IPC;
14821                                 }
14822                                 sip->cmd = si->cmd;
14823                                 sip->extra_info = NULL;
14824                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
14825                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14826                                 new_key->frame = sip->frame_req;
14827                                 new_key->pid_mid = pid_mid;
14828                                 g_hash_table_insert(si->ct->matched, new_key, sip);
14829                         }
14830                 } else {
14831                         /* we have seen this packet before; check the
14832                            matching table.
14833                            If we haven't yet seen the reply, we won't
14834                            find the info for it; we don't need it, as
14835                            we only use it to save information, and, as
14836                            we've seen this packet before, we've already
14837                            saved the information.
14838                         */
14839                         key.frame = pinfo->fd->num;
14840                         key.pid_mid = pid_mid;
14841                         sip=g_hash_table_lookup(si->ct->matched, &key);
14842                 }
14843         }
14844
14845         /*
14846          * Pass the "sip" on to subdissectors through "si".
14847          */
14848         si->sip = sip;
14849
14850         if (sip != NULL) {
14851                 /*
14852                  * Put in fields for the frame number of the frame to which
14853                  * this is a response or the frame with the response to this
14854                  * frame - if we know the frame number (i.e., it's not 0).
14855                  */
14856                 if(si->request){
14857                         if (sip->frame_res != 0)
14858                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
14859                 } else {
14860                         if (sip->frame_req != 0) {
14861                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
14862                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
14863                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
14864                                 if(ns.nsecs<0){
14865                                         ns.nsecs+=1000000000;
14866                                         ns.secs--;
14867                                 }
14868                                 proto_tree_add_time(htree, hf_smb_time, tvb,
14869                                     0, 0, &ns);
14870                         }
14871                 }
14872         }
14873
14874         /* smb command */
14875         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);
14876         offset += 1;
14877
14878         if(flags2 & 0x4000){
14879                 /* handle NT 32 bit error code */
14880
14881                 nt_status = tvb_get_letohl(tvb, offset);
14882
14883                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
14884                         TRUE);
14885                 offset += 4;
14886
14887         } else {
14888                 /* handle DOS error code & class */
14889                 errclass = tvb_get_guint8(tvb, offset);
14890                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
14891                         errclass);
14892                 offset += 1;
14893
14894                 /* reserved byte */
14895                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
14896                 offset += 1;
14897
14898                 /* error code */
14899                 /* XXX - the type of this field depends on the value of
14900                  * "errcls", so there is isn't a single value_string array
14901                  * fo it, so there can't be a single field for it.
14902                  */
14903                 errcode = tvb_get_letohs(tvb, offset);
14904                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
14905                         offset, 2, errcode, "Error Code: %s",
14906                         decode_smb_error(errclass, errcode));
14907                 offset += 2;
14908         }
14909
14910         /* flags */
14911         offset = dissect_smb_flags(tvb, htree, offset);
14912
14913         /* flags2 */
14914         offset = dissect_smb_flags2(tvb, htree, offset);
14915
14916         /*
14917          * The document at
14918          *
14919          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
14920          *
14921          * (a text version of "Microsoft Networks SMB FILE SHARING
14922          * PROTOCOL, Document Version 6.0p") says that:
14923          *
14924          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
14925          *      the "High Part of PID";
14926          *
14927          *      the next four bytes are reserved;
14928          *
14929          *      the next four bytes are, for SMB-over-IPX (with no
14930          *      NetBIOS involved) two bytes of Session ID and two bytes
14931          *      of SequenceNumber.
14932          *
14933          * Network Monitor 2.x dissects the four bytes before the Session ID
14934          * as a "Key", and the two bytes after the SequenceNumber as
14935          * a "Group ID".
14936          *
14937          * The "High Part of PID" has been seen in calls other than NT
14938          * Create and X, although most of them appear to be I/O on DCE RPC
14939          * pipes opened with the NT Create and X in question.
14940          */
14941         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
14942         offset += 2;
14943
14944         if (pinfo->ptype == PT_IPX &&
14945             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
14946              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
14947              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
14948                 /*
14949                  * This is SMB-over-IPX.
14950                  * XXX - do we have to worry about "sequenced commands",
14951                  * as per the Samba document?  They say that for
14952                  * "unsequenced commands" (with a sequence number of 0),
14953                  * the Mid must be unique, but perhaps the Mid doesn't
14954                  * have to be unique for sequenced commands.  In at least
14955                  * one capture with SMB-over-IPX, however, the Mids
14956                  * are unique even for sequenced commands.
14957                  */
14958                 /* Key */
14959                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
14960                     TRUE);
14961                 offset += 4;
14962
14963                 /* Session ID */
14964                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
14965                     TRUE);
14966                 offset += 2;
14967
14968                 /* Sequence number */
14969                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
14970                     TRUE);
14971                 offset += 2;
14972
14973                 /* Group ID */
14974                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
14975                     TRUE);
14976                 offset += 2;
14977         } else {
14978                 /*
14979                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
14980                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
14981                  * bytes after the "High part of PID" are an 8-byte
14982                  * signature ...
14983                  */
14984                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
14985                 offset += 8;
14986
14987                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
14988                 offset += 2;
14989         }
14990
14991         /* TID */
14992         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
14993         offset += 2;
14994
14995         /* PID */
14996         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
14997         offset += 2;
14998
14999         /* UID */
15000         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
15001         offset += 2;
15002
15003         /* MID */
15004         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
15005         offset += 2;
15006
15007         pinfo->private_data = si;
15008
15009         /* tap the packet before the dissectors are called so we still get
15010            the tap listener called even if there is an exception.
15011         */
15012         tap_queue_packet(smb_tap, pinfo, si);
15013         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
15014
15015         /* Append error info from this packet to info string. */
15016         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
15017                 if (flags2 & 0x4000) {
15018                         /*
15019                          * The status is an NT status code; was there
15020                          * an error?
15021                          */
15022                         if ((nt_status & 0xC0000000) == 0xC0000000) {
15023                                 /*
15024                                  * Yes.
15025                                  */
15026                                 col_append_fstr(
15027                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15028                                         val_to_str(nt_status, NT_errors,
15029                                             "Unknown (0x%08X)"));
15030                         }
15031                 } else {
15032                         /*
15033                          * The status is a DOS error class and code; was
15034                          * there an error?
15035                          */
15036                         if (errclass != SMB_SUCCESS) {
15037                                 /*
15038                                  * Yes.
15039                                  */
15040                                 col_append_fstr(
15041                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15042                                         decode_smb_error(errclass, errcode));
15043                         }
15044                 }
15045         }
15046 }
15047
15048 static gboolean
15049 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15050 {
15051         /* must check that this really is a smb packet */
15052         if (!tvb_bytes_exist(tvb, 0, 4))
15053                 return FALSE;
15054
15055         if( (tvb_get_guint8(tvb, 0) != 0xff)
15056             || (tvb_get_guint8(tvb, 1) != 'S')
15057             || (tvb_get_guint8(tvb, 2) != 'M')
15058             || (tvb_get_guint8(tvb, 3) != 'B') ){
15059                 return FALSE;
15060         }
15061
15062         dissect_smb(tvb, pinfo, parent_tree);
15063         return TRUE;
15064 }
15065
15066 void
15067 proto_register_smb(void)
15068 {
15069         static hf_register_info hf[] = {
15070         { &hf_smb_cmd,
15071                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
15072                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
15073
15074         { &hf_smb_word_count,
15075                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
15076                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
15077
15078         { &hf_smb_byte_count,
15079                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
15080                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
15081
15082         { &hf_smb_response_to,
15083                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
15084                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
15085
15086         { &hf_smb_time,
15087                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
15088                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
15089
15090         { &hf_smb_response_in,
15091                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
15092                 NULL, 0, "The response to this packet is in this packet", HFILL }},
15093
15094         { &hf_smb_continuation_to,
15095                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
15096                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
15097
15098         { &hf_smb_nt_status,
15099                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
15100                 VALS(NT_errors), 0, "NT Status code", HFILL }},
15101
15102         { &hf_smb_error_class,
15103                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
15104                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
15105
15106         { &hf_smb_error_code,
15107                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
15108                 NULL, 0, "DOS Error Code", HFILL }},
15109
15110         { &hf_smb_reserved,
15111                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
15112                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
15113
15114         { &hf_smb_sig,
15115                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
15116                 NULL, 0, "Signature bytes", HFILL }},
15117
15118         { &hf_smb_key,
15119                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
15120                 NULL, 0, "SMB-over-IPX Key", HFILL }},
15121
15122         { &hf_smb_session_id,
15123                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
15124                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
15125
15126         { &hf_smb_sequence_num,
15127                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
15128                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
15129
15130         { &hf_smb_group_id,
15131                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
15132                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
15133
15134         { &hf_smb_pid,
15135                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
15136                 NULL, 0, "Process ID", HFILL }},
15137
15138         { &hf_smb_pid_high,
15139                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
15140                 NULL, 0, "Process ID High Bytes", HFILL }},
15141
15142         { &hf_smb_tid,
15143                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
15144                 NULL, 0, "Tree ID", HFILL }},
15145
15146         { &hf_smb_uid,
15147                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
15148                 NULL, 0, "User ID", HFILL }},
15149
15150         { &hf_smb_mid,
15151                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
15152                 NULL, 0, "Multiplex ID", HFILL }},
15153
15154         { &hf_smb_flags_lock,
15155                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
15156                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
15157
15158         { &hf_smb_flags_receive_buffer,
15159                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
15160                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
15161
15162         { &hf_smb_flags_caseless,
15163                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
15164                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
15165
15166         { &hf_smb_flags_canon,
15167                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
15168                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
15169
15170         { &hf_smb_flags_oplock,
15171                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
15172                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
15173
15174         { &hf_smb_flags_notify,
15175                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
15176                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
15177
15178         { &hf_smb_flags_response,
15179                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
15180                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
15181
15182         { &hf_smb_flags2_long_names_allowed,
15183                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
15184                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
15185
15186         { &hf_smb_flags2_ea,
15187                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
15188                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
15189
15190         { &hf_smb_flags2_sec_sig,
15191                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
15192                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
15193
15194         { &hf_smb_flags2_long_names_used,
15195                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
15196                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
15197
15198         { &hf_smb_flags2_esn,
15199                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
15200                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
15201
15202         { &hf_smb_flags2_dfs,
15203                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
15204                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
15205
15206         { &hf_smb_flags2_roe,
15207                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
15208                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
15209
15210         { &hf_smb_flags2_nt_error,
15211                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
15212                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
15213
15214         { &hf_smb_flags2_string,
15215                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
15216                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
15217
15218         { &hf_smb_buffer_format,
15219                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
15220                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
15221
15222         { &hf_smb_dialect_name,
15223                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
15224                 NULL, 0, "Name of dialect", HFILL }},
15225
15226         { &hf_smb_dialect_index,
15227                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
15228                 NULL, 0, "Index of selected dialect", HFILL }},
15229
15230         { &hf_smb_max_trans_buf_size,
15231                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
15232                 NULL, 0, "Maximum transmit buffer size", HFILL }},
15233
15234         { &hf_smb_max_mpx_count,
15235                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
15236                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
15237
15238         { &hf_smb_max_vcs_num,
15239                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
15240                 NULL, 0, "Maximum VCs between client and server", HFILL }},
15241
15242         { &hf_smb_session_key,
15243                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
15244                 NULL, 0, "Unique token identifying this session", HFILL }},
15245
15246         { &hf_smb_server_timezone,
15247                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
15248                 NULL, 0, "Current timezone at server.", HFILL }},
15249
15250         { &hf_smb_encryption_key_length,
15251                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
15252                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
15253
15254         { &hf_smb_encryption_key,
15255                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
15256                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
15257
15258         { &hf_smb_primary_domain,
15259                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
15260                 NULL, 0, "The server's primary domain", HFILL }},
15261
15262         { &hf_smb_server,
15263                 { "Server", "smb.server", FT_STRING, BASE_NONE,
15264                 NULL, 0, "The name of the DC/server", HFILL }},
15265
15266         { &hf_smb_max_raw_buf_size,
15267                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
15268                 NULL, 0, "Maximum raw buffer size", HFILL }},
15269
15270         { &hf_smb_server_guid,
15271                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
15272                 NULL, 0, "Globally unique identifier for this server", HFILL }},
15273
15274         { &hf_smb_security_blob_len,
15275                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
15276                 NULL, 0, "Security blob length", HFILL }},
15277
15278         { &hf_smb_security_blob,
15279                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
15280                 NULL, 0, "Security blob", HFILL }},
15281
15282         { &hf_smb_sm_mode16,
15283                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
15284                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15285
15286         { &hf_smb_sm_password16,
15287                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
15288                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15289
15290         { &hf_smb_sm_mode,
15291                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
15292                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15293
15294         { &hf_smb_sm_password,
15295                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
15296                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15297
15298         { &hf_smb_sm_signatures,
15299                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
15300                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
15301
15302         { &hf_smb_sm_sig_required,
15303                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
15304                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
15305
15306         { &hf_smb_rm_read,
15307                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
15308                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
15309
15310         { &hf_smb_rm_write,
15311                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
15312                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
15313
15314         { &hf_smb_server_date_time,
15315                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
15316                 NULL, 0, "Current date and time at server", HFILL }},
15317
15318         { &hf_smb_server_smb_date,
15319                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
15320                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
15321
15322         { &hf_smb_server_smb_time,
15323                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
15324                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
15325
15326         { &hf_smb_server_cap_raw_mode,
15327                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
15328                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
15329
15330         { &hf_smb_server_cap_mpx_mode,
15331                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
15332                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
15333
15334         { &hf_smb_server_cap_unicode,
15335                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
15336                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
15337
15338         { &hf_smb_server_cap_large_files,
15339                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
15340                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
15341
15342         { &hf_smb_server_cap_nt_smbs,
15343                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
15344                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
15345
15346         { &hf_smb_server_cap_rpc_remote_apis,
15347                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
15348                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
15349
15350         { &hf_smb_server_cap_nt_status,
15351                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
15352                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
15353
15354         { &hf_smb_server_cap_level_ii_oplocks,
15355                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
15356                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
15357
15358         { &hf_smb_server_cap_lock_and_read,
15359                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
15360                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
15361
15362         { &hf_smb_server_cap_nt_find,
15363                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
15364                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15365
15366         { &hf_smb_server_cap_dfs,
15367                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15368                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15369
15370         { &hf_smb_server_cap_infolevel_passthru,
15371                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15372                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15373
15374         { &hf_smb_server_cap_large_readx,
15375                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15376                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15377
15378         { &hf_smb_server_cap_large_writex,
15379                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15380                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15381
15382         { &hf_smb_server_cap_unix,
15383                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15384                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15385
15386         { &hf_smb_server_cap_reserved,
15387                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15388                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15389
15390         { &hf_smb_server_cap_bulk_transfer,
15391                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15392                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15393
15394         { &hf_smb_server_cap_compressed_data,
15395                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15396                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15397
15398         { &hf_smb_server_cap_extended_security,
15399                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
15400                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
15401
15402         { &hf_smb_system_time,
15403                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
15404                 NULL, 0, "System Time", HFILL }},
15405
15406         { &hf_smb_unknown,
15407                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
15408                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
15409
15410         { &hf_smb_dir_name,
15411                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
15412                 NULL, 0, "SMB Directory Name", HFILL }},
15413
15414         { &hf_smb_echo_count,
15415                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
15416                 NULL, 0, "Number of times to echo data back", HFILL }},
15417
15418         { &hf_smb_echo_data,
15419                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
15420                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
15421
15422         { &hf_smb_echo_seq_num,
15423                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
15424                 NULL, 0, "Sequence number for this echo response", HFILL }},
15425
15426         { &hf_smb_max_buf_size,
15427                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
15428                 NULL, 0, "Max client buffer size", HFILL }},
15429
15430         { &hf_smb_path,
15431                 { "Path", "smb.path", FT_STRING, BASE_NONE,
15432                 NULL, 0, "Path. Server name and share name", HFILL }},
15433
15434         { &hf_smb_service,
15435                 { "Service", "smb.service", FT_STRING, BASE_NONE,
15436                 NULL, 0, "Service name", HFILL }},
15437
15438         { &hf_smb_password,
15439                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15440                 NULL, 0, "Password", HFILL }},
15441
15442         { &hf_smb_ansi_password,
15443                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15444                 NULL, 0, "ANSI Password", HFILL }},
15445
15446         { &hf_smb_unicode_password,
15447                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15448                 NULL, 0, "Unicode Password", HFILL }},
15449
15450         { &hf_smb_move_flags_file,
15451                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15452                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15453
15454         { &hf_smb_move_flags_dir,
15455                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15456                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15457
15458         { &hf_smb_move_flags_verify,
15459                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15460                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15461
15462         { &hf_smb_files_moved,
15463                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
15464                 NULL, 0, "Number of files moved", HFILL }},
15465
15466         { &hf_smb_copy_flags_file,
15467                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
15468                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15469
15470         { &hf_smb_copy_flags_dir,
15471                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
15472                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15473
15474         { &hf_smb_copy_flags_dest_mode,
15475                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
15476                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
15477
15478         { &hf_smb_copy_flags_source_mode,
15479                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
15480                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
15481
15482         { &hf_smb_copy_flags_verify,
15483                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
15484                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15485
15486         { &hf_smb_copy_flags_tree_copy,
15487                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
15488                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
15489
15490         { &hf_smb_copy_flags_ea_action,
15491                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
15492                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
15493
15494         { &hf_smb_count,
15495                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
15496                 NULL, 0, "Count number of items/bytes", HFILL }},
15497
15498         { &hf_smb_count_low,
15499                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
15500                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
15501
15502         { &hf_smb_count_high,
15503                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
15504                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
15505
15506         { &hf_smb_file_name,
15507                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
15508                 NULL, 0, "File Name", HFILL }},
15509
15510         { &hf_smb_open_function_create,
15511                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
15512                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
15513
15514         { &hf_smb_open_function_open,
15515                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
15516                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
15517
15518         { &hf_smb_fid,
15519                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
15520                 NULL, 0, "FID: File ID", HFILL }},
15521
15522         { &hf_smb_file_attr_read_only_16bit,
15523                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
15524                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15525
15526         { &hf_smb_file_attr_read_only_8bit,
15527                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
15528                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15529
15530         { &hf_smb_file_attr_hidden_16bit,
15531                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
15532                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15533
15534         { &hf_smb_file_attr_hidden_8bit,
15535                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
15536                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15537
15538         { &hf_smb_file_attr_system_16bit,
15539                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
15540                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15541
15542         { &hf_smb_file_attr_system_8bit,
15543                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
15544                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15545
15546         { &hf_smb_file_attr_volume_16bit,
15547                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
15548                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15549
15550         { &hf_smb_file_attr_volume_8bit,
15551                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
15552                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
15553
15554         { &hf_smb_file_attr_directory_16bit,
15555                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
15556                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15557
15558         { &hf_smb_file_attr_directory_8bit,
15559                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
15560                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15561
15562         { &hf_smb_file_attr_archive_16bit,
15563                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
15564                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15565
15566         { &hf_smb_file_attr_archive_8bit,
15567                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
15568                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15569
15570         { &hf_smb_file_attr_device,
15571                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
15572                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15573
15574         { &hf_smb_file_attr_normal,
15575                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
15576                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15577
15578         { &hf_smb_file_attr_temporary,
15579                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
15580                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15581
15582         { &hf_smb_file_attr_sparse,
15583                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
15584                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15585
15586         { &hf_smb_file_attr_reparse,
15587                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
15588                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15589
15590         { &hf_smb_file_attr_compressed,
15591                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
15592                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15593
15594         { &hf_smb_file_attr_offline,
15595                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
15596                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15597
15598         { &hf_smb_file_attr_not_content_indexed,
15599                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
15600                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15601
15602         { &hf_smb_file_attr_encrypted,
15603                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
15604                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15605
15606         { &hf_smb_file_size,
15607                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
15608                 NULL, 0, "File Size", HFILL }},
15609
15610         { &hf_smb_search_attribute_read_only,
15611                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
15612                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
15613
15614         { &hf_smb_search_attribute_hidden,
15615                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
15616                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
15617
15618         { &hf_smb_search_attribute_system,
15619                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
15620                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
15621
15622         { &hf_smb_search_attribute_volume,
15623                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
15624                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
15625
15626         { &hf_smb_search_attribute_directory,
15627                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
15628                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
15629
15630         { &hf_smb_search_attribute_archive,
15631                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
15632                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
15633
15634         { &hf_smb_access_mode,
15635                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
15636                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
15637
15638         { &hf_smb_access_sharing,
15639                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
15640                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
15641
15642         { &hf_smb_access_locality,
15643                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
15644                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
15645
15646         { &hf_smb_access_caching,
15647                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
15648                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
15649
15650         { &hf_smb_access_writetru,
15651                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
15652                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
15653
15654         { &hf_smb_create_time,
15655                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
15656                 NULL, 0, "Creation Time", HFILL }},
15657
15658         { &hf_smb_modify_time,
15659                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
15660                   NULL, 0, "Modification Time", HFILL }},
15661
15662         { &hf_smb_backup_time,
15663                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
15664                   NULL, 0, "Backup time", HFILL}},
15665
15666         { &hf_smb_mac_alloc_block_count,
15667                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
15668                   NULL, 0, "Allocation Block Count", HFILL}},
15669
15670         { &hf_smb_mac_alloc_block_size,
15671                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
15672                   NULL, 0, "Allocation Block Size", HFILL}},
15673
15674         { &hf_smb_mac_free_block_count,
15675                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
15676                   NULL, 0, "Free Block Count", HFILL}},
15677
15678         { &hf_smb_mac_root_file_count,
15679                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
15680                 NULL, 0, "Root File Count", HFILL}},
15681
15682         { &hf_smb_mac_root_dir_count,
15683           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
15684             NULL, 0, "Root Directory Count", HFILL}},
15685
15686         { &hf_smb_mac_file_count,
15687           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
15688             NULL, 0, "File Count", HFILL}},
15689
15690         { &hf_smb_mac_dir_count,
15691           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
15692             NULL, 0, "Directory Count", HFILL}},
15693
15694         { &hf_smb_mac_support_flags,
15695           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
15696             NULL, 0, "Mac Support Flags", HFILL}},
15697
15698         { &hf_smb_mac_sup_access_ctrl,
15699           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
15700             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
15701
15702         { &hf_smb_mac_sup_getset_comments,
15703           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
15704             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
15705
15706         { &hf_smb_mac_sup_desktopdb_calls,
15707           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
15708             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
15709
15710         { &hf_smb_mac_sup_unique_ids,
15711           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
15712             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
15713
15714         { &hf_smb_mac_sup_streams,
15715           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
15716             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
15717
15718         { &hf_smb_create_dos_date,
15719                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
15720                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
15721
15722         { &hf_smb_create_dos_time,
15723                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
15724                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
15725
15726         { &hf_smb_last_write_time,
15727                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
15728                 NULL, 0, "Time this file was last written to", HFILL }},
15729
15730         { &hf_smb_last_write_dos_date,
15731                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
15732                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
15733
15734         { &hf_smb_last_write_dos_time,
15735                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
15736                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
15737
15738         { &hf_smb_old_file_name,
15739                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
15740                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
15741
15742         { &hf_smb_offset,
15743                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
15744                 NULL, 0, "Offset in file", HFILL }},
15745
15746         { &hf_smb_remaining,
15747                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
15748                 NULL, 0, "Remaining number of bytes", HFILL }},
15749
15750         { &hf_smb_padding,
15751                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
15752                 NULL, 0, "Padding or unknown data", HFILL }},
15753
15754         { &hf_smb_file_data,
15755                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
15756                 NULL, 0, "Data read/written to the file", HFILL }},
15757
15758         { &hf_smb_mac_fndrinfo,
15759                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
15760                   NULL, 0, "Finder Info", HFILL}},
15761
15762         { &hf_smb_total_data_len,
15763                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
15764                 NULL, 0, "Total length of data", HFILL }},
15765
15766         { &hf_smb_data_len,
15767                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
15768                 NULL, 0, "Length of data", HFILL }},
15769
15770         { &hf_smb_data_len_low,
15771                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
15772                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
15773
15774         { &hf_smb_data_len_high,
15775                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
15776                 NULL, 0, "Length of data, High 16 bits", HFILL }},
15777
15778         { &hf_smb_seek_mode,
15779                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
15780                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
15781
15782         { &hf_smb_access_time,
15783                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
15784                 NULL, 0, "Last Access Time", HFILL }},
15785
15786         { &hf_smb_access_dos_date,
15787                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
15788                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
15789
15790         { &hf_smb_access_dos_time,
15791                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
15792                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
15793
15794         { &hf_smb_data_size,
15795                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
15796                 NULL, 0, "Data Size", HFILL }},
15797
15798         { &hf_smb_alloc_size,
15799                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
15800                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15801
15802         { &hf_smb_max_count,
15803                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
15804                 NULL, 0, "Maximum Count", HFILL }},
15805
15806         { &hf_smb_max_count_low,
15807                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
15808                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
15809
15810         { &hf_smb_max_count_high,
15811                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
15812                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
15813
15814         { &hf_smb_min_count,
15815                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
15816                 NULL, 0, "Minimum Count", HFILL }},
15817
15818         { &hf_smb_timeout,
15819                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
15820                 NULL, 0, "Timeout in miliseconds", HFILL }},
15821
15822         { &hf_smb_high_offset,
15823                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
15824                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
15825
15826         { &hf_smb_units,
15827                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
15828                 NULL, 0, "Total number of units at server", HFILL }},
15829
15830         { &hf_smb_bpu,
15831                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
15832                 NULL, 0, "Blocks per unit at server", HFILL }},
15833
15834         { &hf_smb_blocksize,
15835                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
15836                 NULL, 0, "Block size (in bytes) at server", HFILL }},
15837
15838         { &hf_smb_freeunits,
15839                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
15840                 NULL, 0, "Number of free units at server", HFILL }},
15841
15842         { &hf_smb_data_offset,
15843                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15844                 NULL, 0, "Data Offset", HFILL }},
15845
15846         { &hf_smb_dcm,
15847                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
15848                 NULL, 0, "Data Compaction Mode", HFILL }},
15849
15850         { &hf_smb_request_mask,
15851                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
15852                 NULL, 0, "Connectionless mode mask", HFILL }},
15853
15854         { &hf_smb_response_mask,
15855                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
15856                 NULL, 0, "Connectionless mode mask", HFILL }},
15857
15858         { &hf_smb_search_id,
15859                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
15860                 NULL, 0, "Search ID, handle for find operations", HFILL }},
15861
15862         { &hf_smb_write_mode_write_through,
15863                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
15864                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
15865
15866         { &hf_smb_write_mode_return_remaining,
15867                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
15868                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
15869
15870         { &hf_smb_write_mode_raw,
15871                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
15872                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
15873
15874         { &hf_smb_write_mode_message_start,
15875                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
15876                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
15877
15878         { &hf_smb_write_mode_connectionless,
15879                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
15880                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
15881
15882         { &hf_smb_resume_key_len,
15883                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
15884                 NULL, 0, "Resume Key length", HFILL }},
15885
15886         { &hf_smb_resume_find_id,
15887                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
15888                 NULL, 0, "Handle for Find operation", HFILL }},
15889
15890         { &hf_smb_resume_server_cookie,
15891                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
15892                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
15893
15894         { &hf_smb_resume_client_cookie,
15895                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
15896                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
15897
15898         { &hf_smb_andxoffset,
15899                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
15900                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
15901
15902         { &hf_smb_lock_type_large,
15903                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
15904                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
15905
15906         { &hf_smb_lock_type_cancel,
15907                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
15908                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
15909
15910         { &hf_smb_lock_type_change,
15911                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
15912                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
15913
15914         { &hf_smb_lock_type_oplock,
15915                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
15916                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
15917
15918         { &hf_smb_lock_type_shared,
15919                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
15920                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
15921
15922         { &hf_smb_locking_ol,
15923                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
15924                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
15925
15926         { &hf_smb_number_of_locks,
15927                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
15928                 NULL, 0, "Number of lock requests in this request", HFILL }},
15929
15930         { &hf_smb_number_of_unlocks,
15931                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
15932                 NULL, 0, "Number of unlock requests in this request", HFILL }},
15933
15934         { &hf_smb_lock_long_length,
15935                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
15936                 NULL, 0, "Length of lock/unlock region", HFILL }},
15937
15938         { &hf_smb_lock_long_offset,
15939                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
15940                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
15941
15942         { &hf_smb_file_type,
15943                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
15944                 VALS(filetype_vals), 0, "Type of file", HFILL }},
15945
15946         { &hf_smb_ipc_state_nonblocking,
15947                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
15948                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
15949
15950         { &hf_smb_ipc_state_endpoint,
15951                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
15952                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
15953
15954         { &hf_smb_ipc_state_pipe_type,
15955                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
15956                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
15957
15958         { &hf_smb_ipc_state_read_mode,
15959                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
15960                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
15961
15962         { &hf_smb_ipc_state_icount,
15963                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
15964                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
15965
15966         { &hf_smb_server_fid,
15967                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
15968                 NULL, 0, "Server unique File ID", HFILL }},
15969
15970         { &hf_smb_open_flags_add_info,
15971                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
15972                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
15973
15974         { &hf_smb_open_flags_ex_oplock,
15975                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
15976                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
15977
15978         { &hf_smb_open_flags_batch_oplock,
15979                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
15980                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
15981
15982         { &hf_smb_open_flags_ealen,
15983                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
15984                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
15985
15986         { &hf_smb_open_action_open,
15987                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
15988                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
15989
15990         { &hf_smb_open_action_lock,
15991                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
15992                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
15993
15994         { &hf_smb_vc_num,
15995                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
15996                 NULL, 0, "VC Number", HFILL }},
15997
15998         { &hf_smb_password_len,
15999                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
16000                 NULL, 0, "Length of password", HFILL }},
16001
16002         { &hf_smb_ansi_password_len,
16003                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
16004                 NULL, 0, "Length of ANSI password", HFILL }},
16005
16006         { &hf_smb_unicode_password_len,
16007                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
16008                 NULL, 0, "Length of Unicode password", HFILL }},
16009
16010         { &hf_smb_account,
16011                 { "Account", "smb.account", FT_STRING, BASE_NONE,
16012                 NULL, 0, "Account, username", HFILL }},
16013
16014         { &hf_smb_os,
16015                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
16016                 NULL, 0, "Which OS we are running", HFILL }},
16017
16018         { &hf_smb_lanman,
16019                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
16020                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
16021
16022         { &hf_smb_setup_action_guest,
16023                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
16024                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
16025
16026         { &hf_smb_fs,
16027                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
16028                 NULL, 0, "Native File System", HFILL }},
16029
16030         { &hf_smb_connect_flags_dtid,
16031                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
16032                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
16033
16034         { &hf_smb_connect_support_search,
16035                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
16036                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
16037
16038         { &hf_smb_connect_support_in_dfs,
16039                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
16040                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
16041
16042         { &hf_smb_max_setup_count,
16043                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
16044                 NULL, 0, "Maximum number of setup words to return", HFILL }},
16045
16046         { &hf_smb_total_param_count,
16047                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
16048                 NULL, 0, "Total number of parameter bytes", HFILL }},
16049
16050         { &hf_smb_total_data_count,
16051                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
16052                 NULL, 0, "Total number of data bytes", HFILL }},
16053
16054         { &hf_smb_max_param_count,
16055                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
16056                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
16057
16058         { &hf_smb_max_data_count,
16059                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
16060                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
16061
16062         { &hf_smb_param_disp16,
16063                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
16064                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16065
16066         { &hf_smb_param_count16,
16067                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
16068                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16069
16070         { &hf_smb_param_offset16,
16071                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
16072                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16073
16074         { &hf_smb_param_disp32,
16075                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
16076                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16077
16078         { &hf_smb_param_count32,
16079                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
16080                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16081
16082         { &hf_smb_param_offset32,
16083                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
16084                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16085
16086         { &hf_smb_data_count16,
16087                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
16088                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16089
16090         { &hf_smb_data_disp16,
16091                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
16092                 NULL, 0, "Data Displacement", HFILL }},
16093
16094         { &hf_smb_data_offset16,
16095                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16096                 NULL, 0, "Data Offset", HFILL }},
16097
16098         { &hf_smb_data_count32,
16099                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
16100                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16101
16102         { &hf_smb_data_disp32,
16103                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
16104                 NULL, 0, "Data Displacement", HFILL }},
16105
16106         { &hf_smb_data_offset32,
16107                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
16108                 NULL, 0, "Data Offset", HFILL }},
16109
16110         { &hf_smb_setup_count,
16111                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
16112                 NULL, 0, "Number of setup words in this buffer", HFILL }},
16113
16114         { &hf_smb_nt_trans_subcmd,
16115                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16116                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16117
16118         { &hf_smb_nt_ioctl_function_code,
16119                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
16120                 NULL, 0, "NT IOCTL function code", HFILL }},
16121
16122         { &hf_smb_nt_ioctl_isfsctl,
16123                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
16124                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
16125
16126         { &hf_smb_nt_ioctl_flags_root_handle,
16127                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
16128                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
16129
16130         { &hf_smb_nt_ioctl_data,
16131                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
16132                 NULL, 0, "Data for the IOCTL call", HFILL }},
16133
16134         { &hf_smb_nt_notify_action,
16135                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
16136                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
16137
16138         { &hf_smb_nt_notify_watch_tree,
16139                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
16140                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
16141
16142         { &hf_smb_nt_notify_stream_write,
16143                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
16144                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
16145
16146         { &hf_smb_nt_notify_stream_size,
16147                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
16148                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
16149
16150         { &hf_smb_nt_notify_stream_name,
16151                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
16152                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
16153
16154         { &hf_smb_nt_notify_security,
16155                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
16156                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
16157
16158         { &hf_smb_nt_notify_ea,
16159                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
16160                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
16161
16162         { &hf_smb_nt_notify_creation,
16163                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
16164                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
16165
16166         { &hf_smb_nt_notify_last_access,
16167                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
16168                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
16169
16170         { &hf_smb_nt_notify_last_write,
16171                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
16172                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
16173
16174         { &hf_smb_nt_notify_size,
16175                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
16176                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
16177
16178         { &hf_smb_nt_notify_attributes,
16179                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
16180                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
16181
16182         { &hf_smb_nt_notify_dir_name,
16183                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
16184                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
16185
16186         { &hf_smb_nt_notify_file_name,
16187                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
16188                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
16189
16190         { &hf_smb_root_dir_fid,
16191                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
16192                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
16193
16194         { &hf_smb_alloc_size64,
16195                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
16196                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16197
16198         { &hf_smb_nt_create_disposition,
16199                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
16200                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
16201
16202         { &hf_smb_sd_length,
16203                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
16204                 NULL, 0, "Total length of security descriptor", HFILL }},
16205
16206         { &hf_smb_ea_list_length,
16207                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
16208                 NULL, 0, "Total length of extended attributes", HFILL }},
16209
16210         { &hf_smb_ea_flags,
16211                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
16212                 NULL, 0, "EA Flags", HFILL }},
16213
16214         { &hf_smb_ea_name_length,
16215                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
16216                 NULL, 0, "EA Name Length", HFILL }},
16217
16218         { &hf_smb_ea_data_length,
16219                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
16220                 NULL, 0, "EA Data Length", HFILL }},
16221
16222         { &hf_smb_ea_name,
16223                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
16224                 NULL, 0, "EA Name", HFILL }},
16225
16226         { &hf_smb_ea_data,
16227                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
16228                 NULL, 0, "EA Data", HFILL }},
16229
16230         { &hf_smb_file_name_len,
16231                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
16232                 NULL, 0, "Length of File Name", HFILL }},
16233
16234         { &hf_smb_nt_impersonation_level,
16235                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
16236                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
16237
16238         { &hf_smb_nt_security_flags_context_tracking,
16239                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
16240                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
16241
16242         { &hf_smb_nt_security_flags_effective_only,
16243                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
16244                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
16245
16246         { &hf_smb_nt_access_mask_generic_read,
16247                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
16248                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
16249
16250         { &hf_smb_nt_access_mask_generic_write,
16251                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
16252                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
16253
16254         { &hf_smb_nt_access_mask_generic_execute,
16255                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
16256                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
16257
16258         { &hf_smb_nt_access_mask_generic_all,
16259                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
16260                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
16261
16262         { &hf_smb_nt_access_mask_maximum_allowed,
16263                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
16264                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
16265
16266         { &hf_smb_nt_access_mask_system_security,
16267                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
16268                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
16269
16270         { &hf_smb_nt_access_mask_synchronize,
16271                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
16272                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
16273
16274         { &hf_smb_nt_access_mask_write_owner,
16275                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
16276                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
16277
16278         { &hf_smb_nt_access_mask_write_dac,
16279                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
16280                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
16281
16282         { &hf_smb_nt_access_mask_read_control,
16283                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
16284                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
16285
16286         { &hf_smb_nt_access_mask_delete,
16287                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
16288                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
16289
16290         { &hf_smb_nt_access_mask_write_attributes,
16291                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
16292                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
16293
16294         { &hf_smb_nt_access_mask_read_attributes,
16295                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
16296                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
16297
16298         { &hf_smb_nt_access_mask_delete_child,
16299                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
16300                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
16301
16302         /*
16303          * "Execute" for files, "traverse" for directories.
16304          */
16305         { &hf_smb_nt_access_mask_execute,
16306                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
16307                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
16308
16309         { &hf_smb_nt_access_mask_write_ea,
16310                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
16311                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
16312
16313         { &hf_smb_nt_access_mask_read_ea,
16314                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
16315                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
16316
16317         /*
16318          * "Append data" for files, "add subdirectory" for directories,
16319          * "create pipe instance" for named pipes.
16320          */
16321         { &hf_smb_nt_access_mask_append,
16322                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
16323                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
16324
16325         /*
16326          * "Write data" for files and pipes, "add file" for directory.
16327          */
16328         { &hf_smb_nt_access_mask_write,
16329                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
16330                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
16331
16332         /*
16333          * "Read data" for files and pipes, "list directory" for directory.
16334          */
16335         { &hf_smb_nt_access_mask_read,
16336                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
16337                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
16338
16339         { &hf_smb_nt_create_bits_oplock,
16340                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
16341                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
16342
16343         { &hf_smb_nt_create_bits_boplock,
16344                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
16345                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
16346
16347         { &hf_smb_nt_create_bits_dir,
16348                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
16349                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
16350
16351         { &hf_smb_nt_create_bits_ext_resp,
16352           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
16353             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
16354
16355         { &hf_smb_nt_create_options_directory_file,
16356                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
16357                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
16358
16359         { &hf_smb_nt_create_options_write_through,
16360                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
16361                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
16362
16363         { &hf_smb_nt_create_options_sequential_only,
16364                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
16365                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
16366
16367         { &hf_smb_nt_create_options_sync_io_alert,
16368                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
16369                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
16370
16371         { &hf_smb_nt_create_options_sync_io_nonalert,
16372                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
16373                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
16374
16375         { &hf_smb_nt_create_options_non_directory_file,
16376                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
16377                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
16378
16379         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
16380            and "NtOpenFile()"; is that sent over the wire?  Network
16381            Monitor thinks so, but its author may just have grabbed
16382            the flag bits from a system header file. */
16383
16384         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
16385            and "NtOpenFile()"; is that sent over the wire?  NetMon
16386            thinks so, but see previous comment. */
16387
16388         { &hf_smb_nt_create_options_no_ea_knowledge,
16389                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
16390                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
16391
16392         { &hf_smb_nt_create_options_eight_dot_three_only,
16393                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
16394                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
16395
16396         { &hf_smb_nt_create_options_random_access,
16397                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
16398                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
16399
16400         { &hf_smb_nt_create_options_delete_on_close,
16401                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
16402                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
16403
16404         /* 0x00002000 is "open by FID", or something such as that (which
16405            I suspect is like "open by inumber" on UNIX), at least in
16406            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
16407            wire?  NetMon thinks so, but see previous comment. */
16408
16409         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
16410            and "NtOpenFile()"; is that sent over the wire?  NetMon
16411            thinks so, but see previous comment. */
16412
16413         { &hf_smb_nt_share_access_read,
16414                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
16415                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
16416
16417         { &hf_smb_nt_share_access_write,
16418                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
16419                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
16420
16421         { &hf_smb_nt_share_access_delete,
16422                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
16423                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
16424
16425         { &hf_smb_file_eattr_read_only,
16426                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
16427                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16428
16429         { &hf_smb_file_eattr_hidden,
16430                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
16431                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16432
16433         { &hf_smb_file_eattr_system,
16434                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
16435                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16436
16437         { &hf_smb_file_eattr_volume,
16438                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
16439                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16440
16441         { &hf_smb_file_eattr_directory,
16442                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
16443                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16444
16445         { &hf_smb_file_eattr_archive,
16446                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
16447                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16448
16449         { &hf_smb_file_eattr_device,
16450                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
16451                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16452
16453         { &hf_smb_file_eattr_normal,
16454                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
16455                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16456
16457         { &hf_smb_file_eattr_temporary,
16458                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
16459                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16460
16461         { &hf_smb_file_eattr_sparse,
16462                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
16463                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16464
16465         { &hf_smb_file_eattr_reparse,
16466                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
16467                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16468
16469         { &hf_smb_file_eattr_compressed,
16470                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
16471                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16472
16473         { &hf_smb_file_eattr_offline,
16474                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
16475                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16476
16477         { &hf_smb_file_eattr_not_content_indexed,
16478                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
16479                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16480
16481         { &hf_smb_file_eattr_encrypted,
16482                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
16483                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16484
16485         { &hf_smb_sec_desc_len,
16486                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
16487                 NULL, 0, "Security Descriptor Length", HFILL }},
16488
16489         { &hf_smb_nt_qsd_owner,
16490                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
16491                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
16492
16493         { &hf_smb_nt_qsd_group,
16494                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
16495                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
16496
16497         { &hf_smb_nt_qsd_dacl,
16498                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
16499                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
16500
16501         { &hf_smb_nt_qsd_sacl,
16502                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
16503                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
16504
16505         { &hf_smb_extended_attributes,
16506                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
16507                 NULL, 0, "Extended Attributes", HFILL }},
16508
16509         { &hf_smb_oplock_level,
16510                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
16511                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
16512
16513         { &hf_smb_create_action,
16514                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
16515                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
16516
16517         { &hf_smb_file_id,
16518                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
16519                 NULL, 0, "Server unique file ID", HFILL }},
16520
16521         { &hf_smb_ea_error_offset,
16522                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
16523                 NULL, 0, "Offset into EA list if EA error", HFILL }},
16524
16525         { &hf_smb_end_of_file,
16526                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
16527                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
16528
16529         { &hf_smb_replace,
16530                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
16531                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
16532
16533         { &hf_smb_root_dir_handle,
16534                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
16535                 NULL, 0, "Root directory handle", HFILL }},
16536
16537         { &hf_smb_target_name_len,
16538                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
16539                 NULL, 0, "Length of target file name", HFILL }},
16540
16541         { &hf_smb_target_name,
16542                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
16543                 NULL, 0, "Target file name", HFILL }},
16544
16545         { &hf_smb_device_type,
16546                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
16547                 VALS(device_type_vals), 0, "Type of device", HFILL }},
16548
16549         { &hf_smb_is_directory,
16550                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
16551                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
16552
16553         { &hf_smb_next_entry_offset,
16554                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
16555                 NULL, 0, "Offset to next entry", HFILL }},
16556
16557         { &hf_smb_change_time,
16558                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
16559                 NULL, 0, "Last Change Time", HFILL }},
16560
16561         { &hf_smb_setup_len,
16562                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
16563                 NULL, 0, "Length of printer setup data", HFILL }},
16564
16565         { &hf_smb_print_mode,
16566                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
16567                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
16568
16569         { &hf_smb_print_identifier,
16570                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
16571                 NULL, 0, "Identifier string for this print job", HFILL }},
16572
16573         { &hf_smb_restart_index,
16574                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16575                 NULL, 0, "Index of entry after last returned", HFILL }},
16576
16577         { &hf_smb_print_queue_date,
16578                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16579                 NULL, 0, "Date when this entry was queued", HFILL }},
16580
16581         { &hf_smb_print_queue_dos_date,
16582                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16583                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16584
16585         { &hf_smb_print_queue_dos_time,
16586                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
16587                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
16588
16589         { &hf_smb_print_status,
16590                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
16591                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
16592
16593         { &hf_smb_print_spool_file_number,
16594                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
16595                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
16596
16597         { &hf_smb_print_spool_file_size,
16598                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
16599                 NULL, 0, "Number of bytes in spool file", HFILL }},
16600
16601         { &hf_smb_print_spool_file_name,
16602                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
16603                 NULL, 0, "Name of client that submitted this job", HFILL }},
16604
16605         { &hf_smb_start_index,
16606                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
16607                 NULL, 0, "First queue entry to return", HFILL }},
16608
16609         { &hf_smb_originator_name,
16610                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
16611                 NULL, 0, "Name of sender of message", HFILL }},
16612
16613         { &hf_smb_destination_name,
16614                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
16615                 NULL, 0, "Name of recipient of message", HFILL }},
16616
16617         { &hf_smb_message_len,
16618                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
16619                 NULL, 0, "Length of message", HFILL }},
16620
16621         { &hf_smb_message,
16622                 { "Message", "smb.message", FT_STRING, BASE_NONE,
16623                 NULL, 0, "Message text", HFILL }},
16624
16625         { &hf_smb_mgid,
16626                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
16627                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
16628
16629         { &hf_smb_forwarded_name,
16630                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
16631                 NULL, 0, "Recipient name being forwarded", HFILL }},
16632
16633         { &hf_smb_machine_name,
16634                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
16635                 NULL, 0, "Name of target machine", HFILL }},
16636
16637         { &hf_smb_cancel_to,
16638                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
16639                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
16640
16641         { &hf_smb_trans2_subcmd,
16642                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16643                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16644
16645         { &hf_smb_trans_name,
16646                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
16647                 NULL, 0, "Name of transaction", HFILL }},
16648
16649         { &hf_smb_transaction_flags_dtid,
16650                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
16651                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
16652
16653         { &hf_smb_transaction_flags_owt,
16654                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
16655                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
16656
16657         { &hf_smb_search_count,
16658                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
16659                 NULL, 0, "Maximum number of search entries to return", HFILL }},
16660
16661         { &hf_smb_search_pattern,
16662                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
16663                 NULL, 0, "Search Pattern", HFILL }},
16664
16665         { &hf_smb_ff2_backup,
16666                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
16667                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
16668
16669         { &hf_smb_ff2_continue,
16670                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
16671                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
16672
16673         { &hf_smb_ff2_resume,
16674                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
16675                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
16676
16677         { &hf_smb_ff2_close_eos,
16678                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
16679                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
16680
16681         { &hf_smb_ff2_close,
16682                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
16683                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
16684
16685         { &hf_smb_ff2_information_level,
16686                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
16687                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
16688
16689         { &hf_smb_qpi_loi,
16690                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
16691                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
16692
16693         { &hf_smb_spi_loi,
16694                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
16695                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
16696
16697 #if 0
16698         { &hf_smb_sfi_writetru,
16699                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
16700                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
16701
16702         { &hf_smb_sfi_caching,
16703                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
16704                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
16705 #endif
16706
16707         { &hf_smb_storage_type,
16708                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
16709                 NULL, 0, "Type of storage", HFILL }},
16710
16711         { &hf_smb_resume,
16712                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
16713                 NULL, 0, "Resume Key", HFILL }},
16714
16715         { &hf_smb_max_referral_level,
16716                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
16717                 NULL, 0, "Latest referral version number understood", HFILL }},
16718
16719         { &hf_smb_qfsi_information_level,
16720                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
16721                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
16722
16723         { &hf_smb_nt_rename_level,
16724                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
16725                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
16726
16727         { &hf_smb_cluster_count,
16728                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
16729                 NULL, 0, "Number of clusters", HFILL }},
16730
16731         { &hf_smb_number_of_links,
16732                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
16733                 NULL, 0, "Number of hard links to the file", HFILL }},
16734
16735         { &hf_smb_delete_pending,
16736                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
16737                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
16738
16739         { &hf_smb_index_number,
16740                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
16741                 NULL, 0, "File system unique identifier", HFILL }},
16742
16743         { &hf_smb_current_offset,
16744                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
16745                 NULL, 0, "Current offset in the file", HFILL }},
16746
16747         { &hf_smb_t2_alignment,
16748                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
16749                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
16750
16751         { &hf_smb_t2_stream_name_length,
16752                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
16753                 NULL, 0, "Length of stream name", HFILL }},
16754
16755         { &hf_smb_t2_stream_size,
16756                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
16757                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16758
16759         { &hf_smb_t2_stream_name,
16760                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
16761                 NULL, 0, "Name of the stream", HFILL }},
16762
16763         { &hf_smb_t2_compressed_file_size,
16764                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
16765                 NULL, 0, "Size of the compressed file", HFILL }},
16766
16767         { &hf_smb_t2_compressed_format,
16768                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
16769                 NULL, 0, "Compression algorithm used", HFILL }},
16770
16771         { &hf_smb_t2_compressed_unit_shift,
16772                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
16773                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16774
16775         { &hf_smb_t2_compressed_chunk_shift,
16776                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
16777                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16778
16779         { &hf_smb_t2_compressed_cluster_shift,
16780                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
16781                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16782
16783         { &hf_smb_t2_marked_for_deletion,
16784                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
16785                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
16786
16787         { &hf_smb_dfs_path_consumed,
16788                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
16789                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
16790
16791         { &hf_smb_dfs_num_referrals,
16792                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
16793                 NULL, 0, "Number of referrals in this pdu", HFILL }},
16794
16795         { &hf_smb_get_dfs_server_hold_storage,
16796                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
16797                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
16798
16799         { &hf_smb_get_dfs_fielding,
16800                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
16801                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
16802
16803         { &hf_smb_dfs_referral_version,
16804                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
16805                 NULL, 0, "Version of referral element", HFILL }},
16806
16807         { &hf_smb_dfs_referral_size,
16808                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
16809                 NULL, 0, "Size of referral element", HFILL }},
16810
16811         { &hf_smb_dfs_referral_server_type,
16812                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
16813                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
16814
16815         { &hf_smb_dfs_referral_flags_strip,
16816                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
16817                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
16818
16819         { &hf_smb_dfs_referral_node_offset,
16820                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
16821                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
16822
16823         { &hf_smb_dfs_referral_node,
16824                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
16825                 NULL, 0, "Name of entity to visit next", HFILL }},
16826
16827         { &hf_smb_dfs_referral_proximity,
16828                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
16829                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
16830
16831         { &hf_smb_dfs_referral_ttl,
16832                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
16833                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
16834
16835         { &hf_smb_dfs_referral_path_offset,
16836                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
16837                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
16838
16839         { &hf_smb_dfs_referral_path,
16840                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
16841                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
16842
16843         { &hf_smb_dfs_referral_alt_path_offset,
16844                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
16845                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
16846
16847         { &hf_smb_dfs_referral_alt_path,
16848                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
16849                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
16850
16851         { &hf_smb_end_of_search,
16852                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
16853                 NULL, 0, "Was last entry returned?", HFILL }},
16854
16855         { &hf_smb_last_name_offset,
16856                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
16857                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
16858
16859         { &hf_smb_fn_information_level,
16860                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
16861                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
16862
16863         { &hf_smb_monitor_handle,
16864                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
16865                 NULL, 0, "Handle for Find Notify operations", HFILL }},
16866
16867         { &hf_smb_change_count,
16868                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
16869                 NULL, 0, "Number of changes to wait for", HFILL }},
16870
16871         { &hf_smb_file_index,
16872                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
16873                 NULL, 0, "File index", HFILL }},
16874
16875         { &hf_smb_short_file_name,
16876                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
16877                 NULL, 0, "Short (8.3) File Name", HFILL }},
16878
16879         { &hf_smb_short_file_name_len,
16880                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
16881                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
16882
16883         { &hf_smb_fs_id,
16884                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
16885                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
16886
16887         { &hf_smb_fs_guid,
16888                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
16889                 NULL, 0, "File System GUID", HFILL }},
16890
16891         { &hf_smb_sector_unit,
16892                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
16893                 NULL, 0, "Sectors per allocation unit", HFILL }},
16894
16895         { &hf_smb_fs_units,
16896                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
16897                 NULL, 0, "Total number of units on this filesystem", HFILL }},
16898
16899         { &hf_smb_fs_sector,
16900                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
16901                 NULL, 0, "Bytes per sector", HFILL }},
16902
16903         { &hf_smb_avail_units,
16904                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
16905                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
16906
16907         { &hf_smb_volume_serial_num,
16908                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
16909                 NULL, 0, "Volume serial number", HFILL }},
16910
16911         { &hf_smb_volume_label_len,
16912                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
16913                 NULL, 0, "Length of volume label", HFILL }},
16914
16915         { &hf_smb_volume_label,
16916                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
16917                 NULL, 0, "Volume label", HFILL }},
16918
16919         { &hf_smb_free_alloc_units64,
16920                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
16921                 NULL, 0, "Number of free allocation units", HFILL }},
16922
16923         { &hf_smb_caller_free_alloc_units64,
16924                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
16925                 NULL, 0, "Number of caller free allocation units", HFILL }},
16926
16927         { &hf_smb_actual_free_alloc_units64,
16928                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
16929                 NULL, 0, "Number of actual free allocation units", HFILL }},
16930
16931         { &hf_smb_soft_quota_limit,
16932                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
16933                 NULL, 0, "Soft Quota treshold", HFILL }},
16934
16935         { &hf_smb_hard_quota_limit,
16936                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
16937                 NULL, 0, "Hard Quota limit", HFILL }},
16938
16939         { &hf_smb_user_quota_used,
16940                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
16941                 NULL, 0, "How much Quota is used by this user", HFILL }},
16942
16943         { &hf_smb_max_name_len,
16944                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
16945                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
16946
16947         { &hf_smb_fs_name_len,
16948                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
16949                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
16950
16951         { &hf_smb_fs_name,
16952                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
16953                 NULL, 0, "Name of filesystem", HFILL }},
16954
16955         { &hf_smb_device_char_removable,
16956                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
16957                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
16958
16959         { &hf_smb_device_char_read_only,
16960                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
16961                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
16962
16963         { &hf_smb_device_char_floppy,
16964                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
16965                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
16966
16967         { &hf_smb_device_char_write_once,
16968                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
16969                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
16970
16971         { &hf_smb_device_char_remote,
16972                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
16973                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
16974
16975         { &hf_smb_device_char_mounted,
16976                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
16977                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
16978
16979         { &hf_smb_device_char_virtual,
16980                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
16981                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
16982
16983         { &hf_smb_fs_attr_css,
16984                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
16985                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
16986
16987         { &hf_smb_fs_attr_cpn,
16988                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
16989                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
16990
16991         { &hf_smb_fs_attr_uod,
16992                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
16993                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
16994
16995         { &hf_smb_fs_attr_pacls,
16996                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
16997                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
16998
16999         { &hf_smb_fs_attr_fc,
17000                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
17001                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
17002
17003         { &hf_smb_fs_attr_vq,
17004                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
17005                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
17006
17007         { &hf_smb_fs_attr_ssf,
17008                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
17009                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
17010
17011         { &hf_smb_fs_attr_srp,
17012                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
17013                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
17014
17015         { &hf_smb_fs_attr_srs,
17016                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
17017                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
17018
17019         { &hf_smb_fs_attr_sla,
17020                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
17021                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
17022
17023         { &hf_smb_fs_attr_vic,
17024                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
17025                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
17026
17027         { &hf_smb_fs_attr_soids,
17028                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
17029                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
17030
17031         { &hf_smb_fs_attr_se,
17032                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
17033                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
17034
17035         { &hf_smb_fs_attr_ns,
17036                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
17037                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
17038
17039         { &hf_smb_fs_attr_rov,
17040                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
17041                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
17042
17043         { &hf_smb_user_quota_offset,
17044                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
17045                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
17046
17047         { &hf_smb_pipe_write_len,
17048                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
17049                 NULL, 0, "Number of bytes written to pipe", HFILL }},
17050
17051         { &hf_smb_quota_flags_deny_disk,
17052                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
17053                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
17054
17055         { &hf_smb_quota_flags_log_limit,
17056                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
17057                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
17058
17059         { &hf_smb_quota_flags_log_warning,
17060                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
17061                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
17062
17063         { &hf_smb_quota_flags_enabled,
17064                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
17065                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
17066
17067         { &hf_smb_segment_overlap,
17068                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17069                         "Fragment overlaps with other fragments", HFILL }},
17070
17071         { &hf_smb_segment_overlap_conflict,
17072                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17073                         "Overlapping fragments contained conflicting data", HFILL }},
17074
17075         { &hf_smb_segment_multiple_tails,
17076                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17077                         "Several tails were found when defragmenting the packet", HFILL }},
17078
17079         { &hf_smb_segment_too_long_fragment,
17080                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17081                         "Fragment contained data past end of packet", HFILL }},
17082
17083         { &hf_smb_segment_error,
17084                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
17085                         "Defragmentation error due to illegal fragments", HFILL }},
17086
17087         { &hf_smb_segment,
17088                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
17089                         "SMB Segment", HFILL }},
17090
17091         { &hf_smb_segments,
17092                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
17093                         "SMB Segments", HFILL }},
17094
17095         { &hf_smb_unix_major_version,
17096           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
17097             NULL, 0, "UNIX Major Version", HFILL }},
17098
17099         { &hf_smb_unix_minor_version,
17100           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
17101             NULL, 0, "UNIX Minor Version", HFILL }},
17102
17103         { &hf_smb_unix_capability_fcntl,
17104           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
17105                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
17106
17107         { &hf_smb_unix_capability_posix_acl,
17108           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
17109                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
17110
17111         { &hf_smb_unix_file_size,
17112           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
17113             NULL, 0, "", HFILL }},
17114
17115         { &hf_smb_unix_file_num_bytes,
17116           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
17117             NULL, 0, "Number of bytes used to store the file", HFILL }},
17118
17119         { &hf_smb_unix_file_last_status,
17120           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
17121             NULL, 0, "", HFILL }},
17122
17123         { &hf_smb_unix_file_last_access,
17124           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
17125             NULL, 0, "", HFILL }},
17126
17127         { &hf_smb_unix_file_last_change,
17128           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
17129             NULL, 0, "", HFILL }},
17130
17131         { &hf_smb_unix_file_uid,
17132           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
17133             NULL, 0, "", HFILL }},
17134
17135         { &hf_smb_unix_file_gid,
17136           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
17137             NULL, 0, "", HFILL }},
17138
17139         { &hf_smb_unix_file_type,
17140           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
17141             VALS(unix_file_type_vals), 0, "", HFILL }},
17142
17143         { &hf_smb_unix_file_dev_major,
17144           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
17145             NULL, 0, "", HFILL }},
17146
17147         { &hf_smb_unix_file_dev_minor,
17148           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
17149             NULL, 0, "", HFILL }},
17150
17151         { &hf_smb_unix_file_unique_id,
17152           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
17153             NULL, 0, "", HFILL }},
17154
17155         { &hf_smb_unix_file_permissions,
17156           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
17157             NULL, 0, "", HFILL }},
17158
17159         { &hf_smb_unix_file_nlinks,
17160           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
17161             NULL, 0, "", HFILL }},
17162
17163         { &hf_smb_unix_file_link_dest,
17164           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
17165             BASE_NONE, NULL, 0, "", HFILL }},
17166
17167         { &hf_smb_unix_find_file_nextoffset,
17168           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
17169             NULL, 0, "", HFILL }},
17170
17171         { &hf_smb_unix_find_file_resumekey,
17172           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
17173             NULL, 0, "", HFILL }},
17174         };
17175
17176         static gint *ett[] = {
17177                 &ett_smb,
17178                 &ett_smb_hdr,
17179                 &ett_smb_command,
17180                 &ett_smb_fileattributes,
17181                 &ett_smb_capabilities,
17182                 &ett_smb_aflags,
17183                 &ett_smb_dialect,
17184                 &ett_smb_dialects,
17185                 &ett_smb_mode,
17186                 &ett_smb_rawmode,
17187                 &ett_smb_flags,
17188                 &ett_smb_flags2,
17189                 &ett_smb_desiredaccess,
17190                 &ett_smb_search,
17191                 &ett_smb_file,
17192                 &ett_smb_openfunction,
17193                 &ett_smb_filetype,
17194                 &ett_smb_openaction,
17195                 &ett_smb_writemode,
17196                 &ett_smb_lock_type,
17197                 &ett_smb_ssetupandxaction,
17198                 &ett_smb_optionsup,
17199                 &ett_smb_time_date,
17200                 &ett_smb_move_copy_flags,
17201                 &ett_smb_file_attributes,
17202                 &ett_smb_search_resume_key,
17203                 &ett_smb_search_dir_info,
17204                 &ett_smb_unlocks,
17205                 &ett_smb_unlock,
17206                 &ett_smb_locks,
17207                 &ett_smb_lock,
17208                 &ett_smb_open_flags,
17209                 &ett_smb_ipc_state,
17210                 &ett_smb_open_action,
17211                 &ett_smb_setup_action,
17212                 &ett_smb_connect_flags,
17213                 &ett_smb_connect_support_bits,
17214                 &ett_smb_nt_access_mask,
17215                 &ett_smb_nt_create_bits,
17216                 &ett_smb_nt_create_options,
17217                 &ett_smb_nt_share_access,
17218                 &ett_smb_nt_security_flags,
17219                 &ett_smb_nt_trans_setup,
17220                 &ett_smb_nt_trans_data,
17221                 &ett_smb_nt_trans_param,
17222                 &ett_smb_nt_notify_completion_filter,
17223                 &ett_smb_nt_ioctl_flags,
17224                 &ett_smb_security_information_mask,
17225                 &ett_smb_print_queue_entry,
17226                 &ett_smb_transaction_flags,
17227                 &ett_smb_transaction_params,
17228                 &ett_smb_find_first2_flags,
17229 #if 0
17230                 &ett_smb_ioflag,
17231 #endif
17232                 &ett_smb_transaction_data,
17233                 &ett_smb_stream_info,
17234                 &ett_smb_dfs_referrals,
17235                 &ett_smb_dfs_referral,
17236                 &ett_smb_dfs_referral_flags,
17237                 &ett_smb_get_dfs_flags,
17238                 &ett_smb_ff2_data,
17239                 &ett_smb_device_characteristics,
17240                 &ett_smb_fs_attributes,
17241                 &ett_smb_segments,
17242                 &ett_smb_segment,
17243                 &ett_smb_quotaflags,
17244                 &ett_smb_secblob,
17245                 &ett_smb_mac_support_flags,
17246                 &ett_smb_unicode_password,
17247                 &ett_smb_ea,
17248                 &ett_smb_unix_capabilities
17249         };
17250         module_t *smb_module;
17251
17252         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
17253             "SMB", "smb");
17254         proto_register_subtree_array(ett, array_length(ett));
17255         proto_register_field_array(proto_smb, hf, array_length(hf));
17256
17257         proto_do_register_windows_common(proto_smb);
17258
17259         register_init_routine(&smb_init_protocol);
17260         smb_module = prefs_register_protocol(proto_smb, NULL);
17261         prefs_register_bool_preference(smb_module, "trans_reassembly",
17262                 "Reassemble SMB Transaction payload",
17263                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
17264                 &smb_trans_reassembly);
17265         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
17266                 "Reassemble DCERPC over SMB",
17267                 "Whether the dissector should reassemble DCERPC over SMB commands",
17268                 &smb_dcerpc_reassembly);
17269         prefs_register_bool_preference(smb_module, "sid_name_snooping",
17270                 "Snoop SID to Name mappings",
17271                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
17272                 &sid_name_snooping);
17273
17274         register_init_routine(smb_trans_reassembly_init);
17275         smb_tap = register_tap("smb");
17276 }
17277
17278 void
17279 proto_reg_handoff_smb(void)
17280 {
17281         dissector_handle_t smb_handle;
17282
17283         gssapi_handle = find_dissector("gssapi");
17284         ntlmssp_handle = find_dissector("ntlmssp");
17285
17286         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
17287         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
17288         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
17289         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
17290         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
17291         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
17292         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
17293             smb_handle);
17294 }