Added DOS error 259 - no more items.
[obnox/wireshark/wip.git] / 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: packet-smb.c,v 1.277 2002/08/07 00:48:52 tpot Exp $
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/packet.h>
40 #include <epan/conversation.h>
41 #include "smb.h"
42 #include "alignment.h"
43 #include <epan/strutil.h>
44 #include "prefs.h"
45 #include "reassemble.h"
46
47 #include "packet-smb-mailslot.h"
48 #include "packet-smb-pipe.h"
49
50 /*
51  * Various specifications and documents about SMB can be found in
52  *
53  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
54  *
55  * and a CIFS specification from the Storage Networking Industry Association
56  * can be found on a link from the page at
57  *
58  *      http://www.snia.org/English/Collaterals/Work_Group_Docs/NAS/CIFS/CIFS_Technical_Reference.pdf
59  *
60  * (it supercedes the document at
61  *
62  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
63  *
64  * ).
65  *
66  * There are also some Open Group publications documenting CIFS for sale;
67  * catalog entries for them are at:
68  *
69  *      http://www.opengroup.org/products/publications/catalog/c209.htm
70  *
71  *      http://www.opengroup.org/products/publications/catalog/c195.htm
72  *
73  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
74  * can be found at
75  *
76  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
77  *
78  * (or, presumably a similar path under the Samba mirrors).  As the
79  * ".doc" indicates, it's a Word document.  Some of the specs from the
80  * Microsoft FTP site can be found in the
81  *
82  *      http://www.samba.org/samba/ftp/specs/
83  *
84  * directory as well.
85  *
86  * Beware - these specs may have errors.
87  */
88 static int proto_smb = -1;
89 static int hf_smb_cmd = -1;
90 static int hf_smb_pid = -1;
91 static int hf_smb_tid = -1;
92 static int hf_smb_uid = -1;
93 static int hf_smb_mid = -1;
94 static int hf_smb_response_to = -1;
95 static int hf_smb_time = -1;
96 static int hf_smb_response_in = -1;
97 static int hf_smb_continuation_to = -1;
98 static int hf_smb_nt_status = -1;
99 static int hf_smb_error_class = -1;
100 static int hf_smb_error_code = -1;
101 static int hf_smb_reserved = -1;
102 static int hf_smb_flags_lock = -1;
103 static int hf_smb_flags_receive_buffer = -1;
104 static int hf_smb_flags_caseless = -1;
105 static int hf_smb_flags_canon = -1;
106 static int hf_smb_flags_oplock = -1;
107 static int hf_smb_flags_notify = -1;
108 static int hf_smb_flags_response = -1;
109 static int hf_smb_flags2_long_names_allowed = -1;
110 static int hf_smb_flags2_ea = -1;
111 static int hf_smb_flags2_sec_sig = -1;
112 static int hf_smb_flags2_long_names_used = -1;
113 static int hf_smb_flags2_esn = -1;
114 static int hf_smb_flags2_dfs = -1;
115 static int hf_smb_flags2_roe = -1;
116 static int hf_smb_flags2_nt_error = -1;
117 static int hf_smb_flags2_string = -1;
118 static int hf_smb_word_count = -1;
119 static int hf_smb_byte_count = -1;
120 static int hf_smb_buffer_format = -1;
121 static int hf_smb_dialect_name = -1;
122 static int hf_smb_dialect_index = -1;
123 static int hf_smb_max_trans_buf_size = -1;
124 static int hf_smb_max_mpx_count = -1;
125 static int hf_smb_max_vcs_num = -1;
126 static int hf_smb_session_key = -1;
127 static int hf_smb_server_timezone = -1;
128 static int hf_smb_encryption_key_length = -1;
129 static int hf_smb_encryption_key = -1;
130 static int hf_smb_primary_domain = -1;
131 static int hf_smb_max_raw_buf_size = -1;
132 static int hf_smb_server_guid = -1;
133 static int hf_smb_security_blob_len = -1;
134 static int hf_smb_security_blob = -1;
135 static int hf_smb_sm_mode16 = -1;
136 static int hf_smb_sm_password16 = -1;
137 static int hf_smb_sm_mode = -1;
138 static int hf_smb_sm_password = -1;
139 static int hf_smb_sm_signatures = -1;
140 static int hf_smb_sm_sig_required = -1;
141 static int hf_smb_rm_read = -1;
142 static int hf_smb_rm_write = -1;
143 static int hf_smb_server_date_time = -1;
144 static int hf_smb_server_smb_date = -1;
145 static int hf_smb_server_smb_time = -1;
146 static int hf_smb_server_cap_raw_mode = -1;
147 static int hf_smb_server_cap_mpx_mode = -1;
148 static int hf_smb_server_cap_unicode = -1;
149 static int hf_smb_server_cap_large_files = -1;
150 static int hf_smb_server_cap_nt_smbs = -1;
151 static int hf_smb_server_cap_rpc_remote_apis = -1;
152 static int hf_smb_server_cap_nt_status = -1;
153 static int hf_smb_server_cap_level_ii_oplocks = -1;
154 static int hf_smb_server_cap_lock_and_read = -1;
155 static int hf_smb_server_cap_nt_find = -1;
156 static int hf_smb_server_cap_dfs = -1;
157 static int hf_smb_server_cap_infolevel_passthru = -1;
158 static int hf_smb_server_cap_large_readx = -1;
159 static int hf_smb_server_cap_large_writex = -1;
160 static int hf_smb_server_cap_unix = -1;
161 static int hf_smb_server_cap_reserved = -1;
162 static int hf_smb_server_cap_bulk_transfer = -1;
163 static int hf_smb_server_cap_compressed_data = -1;
164 static int hf_smb_server_cap_extended_security = -1;
165 static int hf_smb_system_time = -1;
166 static int hf_smb_unknown = -1;
167 static int hf_smb_dir_name = -1;
168 static int hf_smb_echo_count = -1;
169 static int hf_smb_echo_data = -1;
170 static int hf_smb_echo_seq_num = -1;
171 static int hf_smb_max_buf_size = -1;
172 static int hf_smb_password = -1;
173 static int hf_smb_password_len = -1;
174 static int hf_smb_ansi_password = -1;
175 static int hf_smb_ansi_password_len = -1;
176 static int hf_smb_unicode_password = -1;
177 static int hf_smb_unicode_password_len = -1;
178 static int hf_smb_path = -1;
179 static int hf_smb_service = -1;
180 static int hf_smb_move_flags_file = -1;
181 static int hf_smb_move_flags_dir = -1;
182 static int hf_smb_move_flags_verify = -1;
183 static int hf_smb_files_moved = -1;
184 static int hf_smb_copy_flags_file = -1;
185 static int hf_smb_copy_flags_dir = -1;
186 static int hf_smb_copy_flags_dest_mode = -1;
187 static int hf_smb_copy_flags_source_mode = -1;
188 static int hf_smb_copy_flags_verify = -1;
189 static int hf_smb_copy_flags_tree_copy = -1;
190 static int hf_smb_copy_flags_ea_action = -1;
191 static int hf_smb_count = -1;
192 static int hf_smb_file_name = -1;
193 static int hf_smb_open_function_open = -1;
194 static int hf_smb_open_function_create = -1;
195 static int hf_smb_fid = -1;
196 static int hf_smb_file_attr_read_only_16bit = -1;
197 static int hf_smb_file_attr_read_only_8bit = -1;
198 static int hf_smb_file_attr_hidden_16bit = -1;
199 static int hf_smb_file_attr_hidden_8bit = -1;
200 static int hf_smb_file_attr_system_16bit = -1;
201 static int hf_smb_file_attr_system_8bit = -1;
202 static int hf_smb_file_attr_volume_16bit = -1;
203 static int hf_smb_file_attr_volume_8bit = -1;
204 static int hf_smb_file_attr_directory_16bit = -1;
205 static int hf_smb_file_attr_directory_8bit = -1;
206 static int hf_smb_file_attr_archive_16bit = -1;
207 static int hf_smb_file_attr_archive_8bit = -1;
208 static int hf_smb_file_attr_device = -1;
209 static int hf_smb_file_attr_normal = -1;
210 static int hf_smb_file_attr_temporary = -1;
211 static int hf_smb_file_attr_sparse = -1;
212 static int hf_smb_file_attr_reparse = -1;
213 static int hf_smb_file_attr_compressed = -1;
214 static int hf_smb_file_attr_offline = -1;
215 static int hf_smb_file_attr_not_content_indexed = -1;
216 static int hf_smb_file_attr_encrypted = -1;
217 static int hf_smb_file_size = -1;
218 static int hf_smb_search_attribute_read_only = -1;
219 static int hf_smb_search_attribute_hidden = -1;
220 static int hf_smb_search_attribute_system = -1;
221 static int hf_smb_search_attribute_volume = -1;
222 static int hf_smb_search_attribute_directory = -1;
223 static int hf_smb_search_attribute_archive = -1;
224 static int hf_smb_access_mode = -1;
225 static int hf_smb_access_sharing = -1;
226 static int hf_smb_access_locality = -1;
227 static int hf_smb_access_caching = -1;
228 static int hf_smb_access_writetru = -1;
229 static int hf_smb_create_time = -1;
230 static int hf_smb_create_dos_date = -1;
231 static int hf_smb_create_dos_time = -1;
232 static int hf_smb_last_write_time = -1;
233 static int hf_smb_last_write_dos_date = -1;
234 static int hf_smb_last_write_dos_time = -1;
235 static int hf_smb_access_time = -1;
236 static int hf_smb_access_dos_date = -1;
237 static int hf_smb_access_dos_time = -1;
238 static int hf_smb_old_file_name = -1;
239 static int hf_smb_offset = -1;
240 static int hf_smb_remaining = -1;
241 static int hf_smb_padding = -1;
242 static int hf_smb_file_data = -1;
243 static int hf_smb_total_data_len = -1;
244 static int hf_smb_data_len = -1;
245 static int hf_smb_seek_mode = -1;
246 static int hf_smb_data_size = -1;
247 static int hf_smb_alloc_size = -1;
248 static int hf_smb_alloc_size64 = -1;
249 static int hf_smb_max_count = -1;
250 static int hf_smb_min_count = -1;
251 static int hf_smb_timeout = -1;
252 static int hf_smb_high_offset = -1;
253 static int hf_smb_units = -1;
254 static int hf_smb_bpu = -1;
255 static int hf_smb_blocksize = -1;
256 static int hf_smb_freeunits = -1;
257 static int hf_smb_data_offset = -1;
258 static int hf_smb_dcm = -1;
259 static int hf_smb_request_mask = -1;
260 static int hf_smb_response_mask = -1;
261 static int hf_smb_sid = -1;
262 static int hf_smb_write_mode_write_through = -1;
263 static int hf_smb_write_mode_return_remaining = -1;
264 static int hf_smb_write_mode_raw = -1;
265 static int hf_smb_write_mode_message_start = -1;
266 static int hf_smb_write_mode_connectionless = -1;
267 static int hf_smb_resume_key_len = -1;
268 static int hf_smb_resume_find_id = -1;
269 static int hf_smb_resume_server_cookie = -1;
270 static int hf_smb_resume_client_cookie = -1;
271 static int hf_smb_andxoffset = -1;
272 static int hf_smb_lock_type_large = -1;
273 static int hf_smb_lock_type_cancel = -1;
274 static int hf_smb_lock_type_change = -1;
275 static int hf_smb_lock_type_oplock = -1;
276 static int hf_smb_lock_type_shared = -1;
277 static int hf_smb_locking_ol = -1;
278 static int hf_smb_number_of_locks = -1;
279 static int hf_smb_number_of_unlocks = -1;
280 static int hf_smb_lock_long_offset = -1;
281 static int hf_smb_lock_long_length = -1;
282 static int hf_smb_file_type = -1;
283 static int hf_smb_ipc_state_nonblocking = -1;
284 static int hf_smb_ipc_state_endpoint = -1;
285 static int hf_smb_ipc_state_pipe_type = -1;
286 static int hf_smb_ipc_state_read_mode = -1;
287 static int hf_smb_ipc_state_icount = -1;
288 static int hf_smb_server_fid = -1;
289 static int hf_smb_open_flags_add_info = -1;
290 static int hf_smb_open_flags_ex_oplock = -1;
291 static int hf_smb_open_flags_batch_oplock = -1;
292 static int hf_smb_open_flags_ealen = -1;
293 static int hf_smb_open_action_open = -1;
294 static int hf_smb_open_action_lock = -1;
295 static int hf_smb_vc_num = -1;
296 static int hf_smb_account = -1;
297 static int hf_smb_os = -1;
298 static int hf_smb_lanman = -1;
299 static int hf_smb_setup_action_guest = -1;
300 static int hf_smb_fs = -1;
301 static int hf_smb_connect_flags_dtid = -1;
302 static int hf_smb_connect_support_search = -1;
303 static int hf_smb_connect_support_in_dfs = -1;
304 static int hf_smb_max_setup_count = -1;
305 static int hf_smb_total_param_count = -1;
306 static int hf_smb_total_data_count = -1;
307 static int hf_smb_max_param_count = -1;
308 static int hf_smb_max_data_count = -1;
309 static int hf_smb_param_disp16 = -1;
310 static int hf_smb_param_count16 = -1;
311 static int hf_smb_param_offset16 = -1;
312 static int hf_smb_param_disp32 = -1;
313 static int hf_smb_param_count32 = -1;
314 static int hf_smb_param_offset32 = -1;
315 static int hf_smb_data_disp16 = -1;
316 static int hf_smb_data_count16 = -1;
317 static int hf_smb_data_offset16 = -1;
318 static int hf_smb_data_disp32 = -1;
319 static int hf_smb_data_count32 = -1;
320 static int hf_smb_data_offset32 = -1;
321 static int hf_smb_setup_count = -1;
322 static int hf_smb_nt_trans_subcmd = -1;
323 static int hf_smb_nt_ioctl_function_code = -1;
324 static int hf_smb_nt_ioctl_isfsctl = -1;
325 static int hf_smb_nt_ioctl_flags_root_handle = -1;
326 static int hf_smb_nt_ioctl_data = -1;
327 #ifdef SMB_UNUSED_HANDLES
328 static int hf_smb_nt_security_information = -1;
329 #endif
330 static int hf_smb_nt_notify_action = -1;
331 static int hf_smb_nt_notify_watch_tree = -1;
332 static int hf_smb_nt_notify_stream_write = -1;
333 static int hf_smb_nt_notify_stream_size = -1;
334 static int hf_smb_nt_notify_stream_name = -1;
335 static int hf_smb_nt_notify_security = -1;
336 static int hf_smb_nt_notify_ea = -1;
337 static int hf_smb_nt_notify_creation = -1;
338 static int hf_smb_nt_notify_last_access = -1;
339 static int hf_smb_nt_notify_last_write = -1;
340 static int hf_smb_nt_notify_size = -1;
341 static int hf_smb_nt_notify_attributes = -1;
342 static int hf_smb_nt_notify_dir_name = -1;
343 static int hf_smb_nt_notify_file_name = -1;
344 static int hf_smb_root_dir_fid = -1;
345 static int hf_smb_nt_create_disposition = -1;
346 static int hf_smb_sd_length = -1;
347 static int hf_smb_ea_length = -1;
348 static int hf_smb_file_name_len = -1;
349 static int hf_smb_nt_impersonation_level = -1;
350 static int hf_smb_nt_security_flags_context_tracking = -1;
351 static int hf_smb_nt_security_flags_effective_only = -1;
352 static int hf_smb_nt_access_mask_generic_read = -1;
353 static int hf_smb_nt_access_mask_generic_write = -1;
354 static int hf_smb_nt_access_mask_generic_execute = -1;
355 static int hf_smb_nt_access_mask_generic_all = -1;
356 static int hf_smb_nt_access_mask_maximum_allowed = -1;
357 static int hf_smb_nt_access_mask_system_security = -1;
358 static int hf_smb_nt_access_mask_synchronize = -1;
359 static int hf_smb_nt_access_mask_write_owner = -1;
360 static int hf_smb_nt_access_mask_write_dac = -1;
361 static int hf_smb_nt_access_mask_read_control = -1;
362 static int hf_smb_nt_access_mask_delete = -1;
363 static int hf_smb_nt_access_mask_write_attributes = -1;
364 static int hf_smb_nt_access_mask_read_attributes = -1;
365 static int hf_smb_nt_access_mask_delete_child = -1;
366 static int hf_smb_nt_access_mask_execute = -1;
367 static int hf_smb_nt_access_mask_write_ea = -1;
368 static int hf_smb_nt_access_mask_read_ea = -1;
369 static int hf_smb_nt_access_mask_append = -1;
370 static int hf_smb_nt_access_mask_write = -1;
371 static int hf_smb_nt_access_mask_read = -1;
372 static int hf_smb_nt_create_bits_oplock = -1;
373 static int hf_smb_nt_create_bits_boplock = -1;
374 static int hf_smb_nt_create_bits_dir = -1;
375 static int hf_smb_nt_create_options_directory_file = -1;
376 static int hf_smb_nt_create_options_write_through = -1;
377 static int hf_smb_nt_create_options_sequential_only = -1;
378 static int hf_smb_nt_create_options_sync_io_alert = -1;
379 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
380 static int hf_smb_nt_create_options_non_directory_file = -1;
381 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
382 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
383 static int hf_smb_nt_create_options_random_access = -1;
384 static int hf_smb_nt_create_options_delete_on_close = -1;
385 static int hf_smb_nt_share_access_read = -1;
386 static int hf_smb_nt_share_access_write = -1;
387 static int hf_smb_nt_share_access_delete = -1;
388 static int hf_smb_file_eattr_read_only = -1;
389 static int hf_smb_file_eattr_hidden = -1;
390 static int hf_smb_file_eattr_system = -1;
391 static int hf_smb_file_eattr_volume = -1;
392 static int hf_smb_file_eattr_directory = -1;
393 static int hf_smb_file_eattr_archive = -1;
394 static int hf_smb_file_eattr_device = -1;
395 static int hf_smb_file_eattr_normal = -1;
396 static int hf_smb_file_eattr_temporary = -1;
397 static int hf_smb_file_eattr_sparse = -1;
398 static int hf_smb_file_eattr_reparse = -1;
399 static int hf_smb_file_eattr_compressed = -1;
400 static int hf_smb_file_eattr_offline = -1;
401 static int hf_smb_file_eattr_not_content_indexed = -1;
402 static int hf_smb_file_eattr_encrypted = -1;
403 static int hf_smb_file_eattr_write_through = -1;
404 static int hf_smb_file_eattr_no_buffering = -1;
405 static int hf_smb_file_eattr_random_access = -1;
406 static int hf_smb_file_eattr_sequential_scan = -1;
407 static int hf_smb_file_eattr_delete_on_close = -1;
408 static int hf_smb_file_eattr_backup_semantics = -1;
409 static int hf_smb_file_eattr_posix_semantics = -1;
410 static int hf_smb_sec_desc_len = -1;
411 static int hf_smb_sec_desc_revision = -1;
412 static int hf_smb_sec_desc_type_owner_defaulted = -1;
413 static int hf_smb_sec_desc_type_group_defaulted = -1;
414 static int hf_smb_sec_desc_type_dacl_present = -1;
415 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
416 static int hf_smb_sec_desc_type_sacl_present = -1;
417 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
418 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
419 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
420 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
421 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
422 static int hf_smb_sec_desc_type_dacl_protected = -1;
423 static int hf_smb_sec_desc_type_sacl_protected = -1;
424 static int hf_smb_sec_desc_type_self_relative = -1;
425 static int hf_smb_sid_revision = -1;
426 static int hf_smb_sid_num_auth = -1;
427 static int hf_smb_acl_revision = -1;
428 static int hf_smb_acl_size = -1;
429 static int hf_smb_acl_num_aces = -1;
430 static int hf_smb_ace_type = -1;
431 static int hf_smb_ace_size = -1;
432 static int hf_smb_ace_flags_object_inherit = -1;
433 static int hf_smb_ace_flags_container_inherit = -1;
434 static int hf_smb_ace_flags_non_propagate_inherit = -1;
435 static int hf_smb_ace_flags_inherit_only = -1;
436 static int hf_smb_ace_flags_inherited_ace = -1;
437 static int hf_smb_ace_flags_successful_access = -1;
438 static int hf_smb_ace_flags_failed_access = -1;
439 static int hf_smb_nt_qsd_owner = -1;
440 static int hf_smb_nt_qsd_group = -1;
441 static int hf_smb_nt_qsd_dacl = -1;
442 static int hf_smb_nt_qsd_sacl = -1;
443 static int hf_smb_extended_attributes = -1;
444 static int hf_smb_oplock_level = -1;
445 static int hf_smb_create_action = -1;
446 static int hf_smb_file_id = -1;
447 static int hf_smb_ea_error_offset = -1;
448 static int hf_smb_end_of_file = -1;
449 static int hf_smb_device_type = -1;
450 static int hf_smb_is_directory = -1;
451 static int hf_smb_next_entry_offset = -1;
452 static int hf_smb_change_time = -1;
453 static int hf_smb_setup_len = -1;
454 static int hf_smb_print_mode = -1;
455 static int hf_smb_print_identifier = -1;
456 static int hf_smb_restart_index = -1;
457 static int hf_smb_print_queue_date = -1;
458 static int hf_smb_print_queue_dos_date = -1;
459 static int hf_smb_print_queue_dos_time = -1;
460 static int hf_smb_print_status = -1;
461 static int hf_smb_print_spool_file_number = -1;
462 static int hf_smb_print_spool_file_size = -1;
463 static int hf_smb_print_spool_file_name = -1;
464 static int hf_smb_start_index = -1;
465 static int hf_smb_originator_name = -1;
466 static int hf_smb_destination_name = -1;
467 static int hf_smb_message_len = -1;
468 static int hf_smb_message = -1;
469 static int hf_smb_mgid = -1;
470 static int hf_smb_forwarded_name = -1;
471 static int hf_smb_machine_name = -1;
472 static int hf_smb_cancel_to = -1;
473 static int hf_smb_trans2_subcmd = -1;
474 static int hf_smb_trans_name = -1;
475 static int hf_smb_transaction_flags_dtid = -1;
476 static int hf_smb_transaction_flags_owt = -1;
477 static int hf_smb_search_count = -1;
478 static int hf_smb_search_pattern = -1;
479 static int hf_smb_ff2_backup = -1;
480 static int hf_smb_ff2_continue = -1;
481 static int hf_smb_ff2_resume = -1;
482 static int hf_smb_ff2_close_eos = -1;
483 static int hf_smb_ff2_close = -1;
484 static int hf_smb_ff2_information_level = -1;
485 static int hf_smb_qpi_loi = -1;
486 #if 0
487 static int hf_smb_sfi_writetru = -1;
488 static int hf_smb_sfi_caching = -1;
489 #endif
490 static int hf_smb_storage_type = -1;
491 static int hf_smb_resume = -1;
492 static int hf_smb_max_referral_level = -1;
493 static int hf_smb_qfsi_information_level = -1;
494 static int hf_smb_ea_size = -1;
495 static int hf_smb_list_length = -1;
496 static int hf_smb_number_of_links = -1;
497 static int hf_smb_delete_pending = -1;
498 static int hf_smb_index_number = -1;
499 static int hf_smb_current_offset = -1;
500 static int hf_smb_t2_alignment = -1;
501 static int hf_smb_t2_stream_name_length = -1;
502 static int hf_smb_t2_stream_size = -1;
503 static int hf_smb_t2_stream_name = -1;
504 static int hf_smb_t2_compressed_file_size = -1;
505 static int hf_smb_t2_compressed_format = -1;
506 static int hf_smb_t2_compressed_unit_shift = -1;
507 static int hf_smb_t2_compressed_chunk_shift = -1;
508 static int hf_smb_t2_compressed_cluster_shift = -1;
509 static int hf_smb_dfs_path_consumed = -1;
510 static int hf_smb_dfs_num_referrals = -1;
511 static int hf_smb_get_dfs_server_hold_storage = -1;
512 static int hf_smb_get_dfs_fielding = -1;
513 static int hf_smb_dfs_referral_version = -1;
514 static int hf_smb_dfs_referral_size = -1;
515 static int hf_smb_dfs_referral_server_type = -1;
516 static int hf_smb_dfs_referral_flags_strip = -1;
517 static int hf_smb_dfs_referral_node_offset = -1;
518 static int hf_smb_dfs_referral_node = -1;
519 static int hf_smb_dfs_referral_proximity = -1;
520 static int hf_smb_dfs_referral_ttl = -1;
521 static int hf_smb_dfs_referral_path_offset = -1;
522 static int hf_smb_dfs_referral_path = -1;
523 static int hf_smb_dfs_referral_alt_path_offset = -1;
524 static int hf_smb_dfs_referral_alt_path = -1;
525 static int hf_smb_end_of_search = -1;
526 static int hf_smb_last_name_offset = -1;
527 static int hf_smb_fn_information_level = -1;
528 static int hf_smb_monitor_handle = -1;
529 static int hf_smb_change_count = -1;
530 static int hf_smb_file_index = -1;
531 static int hf_smb_short_file_name = -1;
532 static int hf_smb_short_file_name_len = -1;
533 static int hf_smb_fs_id = -1;
534 static int hf_smb_sector_unit = -1;
535 static int hf_smb_fs_units = -1;
536 static int hf_smb_fs_sector = -1;
537 static int hf_smb_avail_units = -1;
538 static int hf_smb_volume_serial_num = -1;
539 static int hf_smb_volume_label_len = -1;
540 static int hf_smb_volume_label = -1;
541 static int hf_smb_free_alloc_units64 = -1;
542 static int hf_smb_caller_free_alloc_units64 = -1;
543 static int hf_smb_actual_free_alloc_units64 = -1;
544 static int hf_smb_max_name_len = -1;
545 static int hf_smb_fs_name_len = -1;
546 static int hf_smb_fs_name = -1;
547 static int hf_smb_device_char_removable = -1;
548 static int hf_smb_device_char_read_only = -1;
549 static int hf_smb_device_char_floppy = -1;
550 static int hf_smb_device_char_write_once = -1;
551 static int hf_smb_device_char_remote = -1;
552 static int hf_smb_device_char_mounted = -1;
553 static int hf_smb_device_char_virtual = -1;
554 static int hf_smb_fs_attr_css = -1;
555 static int hf_smb_fs_attr_cpn = -1;
556 static int hf_smb_fs_attr_pacls = -1;
557 static int hf_smb_fs_attr_fc = -1;
558 static int hf_smb_fs_attr_vq = -1;
559 static int hf_smb_fs_attr_dim = -1;
560 static int hf_smb_fs_attr_vic = -1;
561 static int hf_smb_quota_flags_enabled = -1;
562 static int hf_smb_quota_flags_deny_disk = -1;
563 static int hf_smb_quota_flags_log_limit = -1;
564 static int hf_smb_quota_flags_log_warning = -1;
565 static int hf_smb_soft_quota_limit = -1;
566 static int hf_smb_hard_quota_limit = -1;
567 static int hf_smb_user_quota_used = -1;
568 static int hf_smb_user_quota_offset = -1;
569 static int hf_smb_nt_rename_level = -1;
570 static int hf_smb_cluster_count = -1;
571 static int hf_smb_segments = -1;
572 static int hf_smb_segment = -1;
573 static int hf_smb_segment_overlap = -1;
574 static int hf_smb_segment_overlap_conflict = -1;
575 static int hf_smb_segment_multiple_tails = -1;
576 static int hf_smb_segment_too_long_fragment = -1;
577 static int hf_smb_segment_error = -1;
578
579 static gint ett_smb = -1;
580 static gint ett_smb_hdr = -1;
581 static gint ett_smb_command = -1;
582 static gint ett_smb_fileattributes = -1;
583 static gint ett_smb_capabilities = -1;
584 static gint ett_smb_aflags = -1;
585 static gint ett_smb_dialect = -1;
586 static gint ett_smb_dialects = -1;
587 static gint ett_smb_mode = -1;
588 static gint ett_smb_rawmode = -1;
589 static gint ett_smb_flags = -1;
590 static gint ett_smb_flags2 = -1;
591 static gint ett_smb_desiredaccess = -1;
592 static gint ett_smb_search = -1;
593 static gint ett_smb_file = -1;
594 static gint ett_smb_openfunction = -1;
595 static gint ett_smb_filetype = -1;
596 static gint ett_smb_openaction = -1;
597 static gint ett_smb_writemode = -1;
598 static gint ett_smb_lock_type = -1;
599 static gint ett_smb_ssetupandxaction = -1;
600 static gint ett_smb_optionsup = -1;
601 static gint ett_smb_time_date = -1;
602 static gint ett_smb_move_copy_flags = -1;
603 static gint ett_smb_file_attributes = -1;
604 static gint ett_smb_search_resume_key = -1;
605 static gint ett_smb_search_dir_info = -1;
606 static gint ett_smb_unlocks = -1;
607 static gint ett_smb_unlock = -1;
608 static gint ett_smb_locks = -1;
609 static gint ett_smb_lock = -1;
610 static gint ett_smb_open_flags = -1;
611 static gint ett_smb_ipc_state = -1;
612 static gint ett_smb_open_action = -1;
613 static gint ett_smb_setup_action = -1;
614 static gint ett_smb_connect_flags = -1;
615 static gint ett_smb_connect_support_bits = -1;
616 static gint ett_smb_nt_access_mask = -1;
617 static gint ett_smb_nt_create_bits = -1;
618 static gint ett_smb_nt_create_options = -1;
619 static gint ett_smb_nt_share_access = -1;
620 static gint ett_smb_nt_security_flags = -1;
621 static gint ett_smb_nt_trans_setup = -1;
622 static gint ett_smb_nt_trans_data = -1;
623 static gint ett_smb_nt_trans_param = -1;
624 static gint ett_smb_nt_notify_completion_filter = -1;
625 static gint ett_smb_nt_ioctl_flags = -1;
626 static gint ett_smb_security_information_mask = -1;
627 static gint ett_smb_print_queue_entry = -1;
628 static gint ett_smb_transaction_flags = -1;
629 static gint ett_smb_transaction_params = -1;
630 static gint ett_smb_find_first2_flags = -1;
631 #if 0
632 static gint ett_smb_ioflag = -1;
633 #endif
634 static gint ett_smb_transaction_data = -1;
635 static gint ett_smb_stream_info = -1;
636 static gint ett_smb_dfs_referrals = -1;
637 static gint ett_smb_dfs_referral = -1;
638 static gint ett_smb_dfs_referral_flags = -1;
639 static gint ett_smb_get_dfs_flags = -1;
640 static gint ett_smb_ff2_data = -1;
641 static gint ett_smb_device_characteristics = -1;
642 static gint ett_smb_fs_attributes = -1;
643 static gint ett_smb_segments = -1;
644 static gint ett_smb_segment = -1;
645 static gint ett_smb_sec_desc = -1;
646 static gint ett_smb_sid = -1;
647 static gint ett_smb_acl = -1;
648 static gint ett_smb_ace = -1;
649 static gint ett_smb_ace_flags = -1;
650 static gint ett_smb_sec_desc_type = -1;
651 static gint ett_smb_quotaflags = -1;
652
653
654 fragment_items smb_frag_items = {
655         &ett_smb_segment,
656         &ett_smb_segments,
657
658         &hf_smb_segments,
659         &hf_smb_segment,
660         &hf_smb_segment_overlap,
661         &hf_smb_segment_overlap_conflict,
662         &hf_smb_segment_multiple_tails,
663         &hf_smb_segment_too_long_fragment,
664         &hf_smb_segment_error,
665
666         "segments"
667 };
668
669 proto_tree *top_tree=NULL;     /* ugly */
670
671 static char *decode_smb_name(unsigned char);
672 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
673 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
674     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
675     gboolean exactlen, guint16 *bcp);
676
677 /*
678  * Macros for use in the main dissector routines for an SMB.
679  */
680
681 #define WORD_COUNT      \
682         /* Word Count */                                \
683         wc = tvb_get_guint8(tvb, offset);               \
684         proto_tree_add_uint(tree, hf_smb_word_count,    \
685                 tvb, offset, 1, wc);                    \
686         offset += 1;                                    \
687         if(wc==0) goto bytecount;
688
689 #define BYTE_COUNT      \
690         bytecount:                                      \
691         bc = tvb_get_letohs(tvb, offset);               \
692         proto_tree_add_uint(tree, hf_smb_byte_count,    \
693                         tvb, offset, 2, bc);            \
694         offset += 2;                                    \
695         if(bc==0) goto endofcommand;
696
697 #define CHECK_BYTE_COUNT(len)   \
698         if (bc < len) goto endofcommand;
699
700 #define COUNT_BYTES(len)   {\
701         int tmp;            \
702         tmp=len;            \
703         offset += tmp;      \
704         bc -= tmp;          \
705         }
706
707 #define END_OF_SMB      \
708         if (bc != 0) { \
709                 proto_tree_add_text(tree, tvb, offset, bc, \
710                     "Extra byte parameters");           \
711                 offset += bc;                           \
712         }                                               \
713         endofcommand:
714
715 /*
716  * Macros for use in routines called by them.
717  */
718 #define CHECK_BYTE_COUNT_SUBR(len)      \
719         if (*bcp < len) {               \
720                 *trunc = TRUE;          \
721                 return offset;          \
722         }
723
724 #define CHECK_STRING_SUBR(fn)   \
725         if (fn == NULL) {       \
726                 *trunc = TRUE;  \
727                 return offset;  \
728         }
729
730 #define COUNT_BYTES_SUBR(len)   \
731         offset += len;          \
732         *bcp -= len;
733
734 /*
735  * Macros for use when dissecting transaction parameters and data
736  */
737 #define CHECK_BYTE_COUNT_TRANS(len)     \
738         if (bc < len) return offset;
739
740 #define CHECK_STRING_TRANS(fn)  \
741         if (fn == NULL) return offset;
742
743 #define COUNT_BYTES_TRANS(len)  \
744         offset += len;          \
745         bc -= len;
746
747 /*
748  * Macros for use in subrroutines dissecting transaction parameters or data
749  */
750 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
751         if (*bcp < len) return offset;
752
753 #define CHECK_STRING_TRANS_SUBR(fn)     \
754         if (fn == NULL) return offset;
755
756 #define COUNT_BYTES_TRANS_SUBR(len)     \
757         offset += len;                  \
758         *bcp -= len;
759
760
761 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
762    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
763    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
764 static gboolean smb_trans_reassembly = FALSE;
765 gboolean smb_dcerpc_reassembly = FALSE;
766
767 static GHashTable *smb_trans_fragment_table = NULL;
768 GHashTable *dcerpc_fragment_table = NULL;
769
770 static void
771 smb_trans_reassembly_init(void)
772 {
773         fragment_table_init(&smb_trans_fragment_table);
774 }
775 static void
776 smb_dcerpc_reassembly_init(void)
777 {
778         fragment_table_init(&dcerpc_fragment_table);
779 }
780
781
782 static fragment_data *
783 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
784                      int offset, int count, int pos, int totlen)
785 {
786         fragment_data *fd_head=NULL;
787         smb_info_t *si;
788         int more_frags;
789
790         more_frags=totlen>(pos+count);
791
792         si = (smb_info_t *)pinfo->private_data;
793         if (si->sip == NULL) {
794                 /*
795                  * We don't have the frame number of the request.
796                  *
797                  * XXX - is there truly nothing we can do here?
798                  * Can we not separately keep track of the original
799                  * transaction and its continuations, as we did
800                  * at one time?
801                  *
802                  * It is probably not much point in even trying to do something here
803                  * if we have never seen the initial request. Without the initial 
804                  * request we probably miss all parameters and the begining of data
805                  * so we cant even call a subdissector since we can not determine
806                  * which type of transaction call this is.
807                  */
808                 return NULL;
809         }
810
811         if(!pinfo->fd->flags.visited){
812                 fd_head = fragment_add(tvb, offset, pinfo,
813                                        si->sip->frame_req, smb_trans_fragment_table,
814                                        pos, count, more_frags);
815         } else {
816                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
817         }
818
819         /* we only show the defragmented packet for the first fragment,
820            or else we might end up with dissecting one HUGE transaction PDU
821            a LOT of times. (first fragment is the only one containing the setup
822            bytes)
823            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
824            SMBs. Takes a LOT of time dissecting and is not fun.
825         */
826         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
827                 return fd_head;
828         } else {
829                 return NULL;
830         }
831 }
832                 
833
834
835
836
837 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
838    These variables and functions are used to match
839    responses with calls
840    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
841 /*
842  * The information we need to save about a request in order to show the
843  * frame number of the request in the dissection of the reply.
844  */
845 typedef struct  {
846         guint32 frame;
847         guint32 pid_mid;
848 } smb_saved_info_key_t;
849
850 static GMemChunk *smb_saved_info_key_chunk = NULL;
851 static GMemChunk *smb_saved_info_chunk = NULL;
852 static int smb_saved_info_init_count = 200;
853
854 /* unmatched smb_saved_info structures.
855    For unmatched smb_saved_info structures we store the smb_saved_info
856    structure using the MID and the PID as the key.
857
858    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
859    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
860    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
861 */
862 static gint
863 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
864 {
865         register guint32 key1 = (guint32)k1;
866         register guint32 key2 = (guint32)k2;
867         return key1==key2;
868 }
869 static guint
870 smb_saved_info_hash_unmatched(gconstpointer k)
871 {
872         register guint32 key = (guint32)k;
873         return key;
874 }
875
876 /* matched smb_saved_info structures.
877    For matched smb_saved_info structures we store the smb_saved_info
878    structure twice in the table using the frame number, and a combination
879    of the MID and the PID, as the key.
880    The frame number is guaranteed to be unique but if ever someone makes
881    some change that will renumber the frames in a capture we are in BIG trouble.
882    This is not likely though since that would break (among other things) all the
883    reassembly routines as well.
884
885    We also need the MID as there may be more than one SMB request or reply
886    in a single frame, and we also need the PID as there may be more than
887    one outstanding request with the same MID and different PIDs.
888 */
889 static gint
890 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
891 {
892         const smb_saved_info_key_t *key1 = k1;
893         const smb_saved_info_key_t *key2 = k2;
894         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
895 }
896 static guint
897 smb_saved_info_hash_matched(gconstpointer k)
898 {
899         const smb_saved_info_key_t *key = k;
900         return key->frame + key->pid_mid;
901 }
902
903 /*
904  * The information we need to save about an NT Transaction request in order
905  * to dissect the reply.
906  */
907 typedef struct {
908         int subcmd;
909 } smb_nt_transact_info_t;
910
911 static GMemChunk *smb_nt_transact_info_chunk = NULL;
912 static int smb_nt_transact_info_init_count = 200;
913
914 /*
915  * The information we need to save about a Transaction2 request in order
916  * to dissect the reply.
917  */
918 typedef struct {
919         int subcmd;
920         int info_level;
921         gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
922 } smb_transact2_info_t;
923
924 static GMemChunk *smb_transact2_info_chunk = NULL;
925 static int smb_transact2_info_init_count = 200;
926
927 /*
928  * The information we need to save about a Transaction request in order
929  * to dissect the reply; this includes information for use by the
930  * Remote API dissector.
931  */
932 static GMemChunk *smb_transact_info_chunk = NULL;
933 static int smb_transact_info_init_count = 200;
934
935 static GMemChunk *conv_tables_chunk = NULL;
936 static GSList *conv_tables = NULL;
937 static int conv_tables_count = 10;
938
939
940 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
941    End of request/response matching functions
942    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
943
944 static const value_string buffer_format_vals[] = {
945         {1,     "Data Block"},
946         {2,     "Dialect"},
947         {3,     "Pathname"},
948         {4,     "ASCII"},
949         {5,     "Variable Block"},
950         {0,     NULL}
951 };
952
953 /*
954  * UTIME - this is *almost* like a UNIX time stamp, except that it's
955  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
956  * January 1, 1970, 00:00:00 GMT.
957  *
958  * This means we have to do some extra work to convert it.  This code is
959  * based on the Samba code:
960  *
961  *      Unix SMB/Netbios implementation.
962  *      Version 1.9.
963  *      time handling functions
964  *      Copyright (C) Andrew Tridgell 1992-1998
965  */
966
967 /*
968  * Yield the difference between *A and *B, in seconds, ignoring leap
969  * seconds.
970  */
971 #define TM_YEAR_BASE 1900
972
973 static int
974 tm_diff(struct tm *a, struct tm *b)
975 {
976         int ay = a->tm_year + (TM_YEAR_BASE - 1);
977         int by = b->tm_year + (TM_YEAR_BASE - 1);
978         int intervening_leap_days =
979             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
980         int years = ay - by;
981         int days =
982             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
983         int hours = 24*days + (a->tm_hour - b->tm_hour);
984         int minutes = 60*hours + (a->tm_min - b->tm_min);
985         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
986
987         return seconds;
988 }
989
990 /*
991  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
992  * determined.
993  */
994 static int
995 TimeZone(time_t t)
996 {
997         struct tm *tm = gmtime(&t);
998         struct tm tm_utc;
999
1000         if (tm == NULL)
1001                 return 0;
1002         tm_utc = *tm;
1003         tm = localtime(&t);
1004         if (tm == NULL)
1005                 return 0;
1006         return tm_diff(&tm_utc,tm);
1007 }
1008
1009 /*
1010  * Return the same value as TimeZone, but it should be more efficient.
1011  *
1012  * We keep a table of DST offsets to prevent calling localtime() on each 
1013  * call of this function. This saves a LOT of time on many unixes.
1014  *
1015  * Updated by Paul Eggert <eggert@twinsun.com>
1016  */
1017 #ifndef CHAR_BIT
1018 #define CHAR_BIT 8
1019 #endif
1020
1021 #ifndef TIME_T_MIN
1022 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1023                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1024 #endif
1025 #ifndef TIME_T_MAX
1026 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1027 #endif
1028
1029 static int
1030 TimeZoneFaster(time_t t)
1031 {
1032         static struct dst_table {time_t start,end; int zone;} *tdt;
1033         static struct dst_table *dst_table = NULL;
1034         static int table_size = 0;
1035         int i;
1036         int zone = 0;
1037
1038         if (t == 0)
1039                 t = time(NULL);
1040
1041         /* Tunis has a 8 day DST region, we need to be careful ... */
1042 #define MAX_DST_WIDTH (365*24*60*60)
1043 #define MAX_DST_SKIP (7*24*60*60)
1044
1045         for (i = 0; i < table_size; i++) {
1046                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1047                         break;
1048         }
1049
1050         if (i < table_size) {
1051                 zone = dst_table[i].zone;
1052         } else {
1053                 time_t low,high;
1054
1055                 zone = TimeZone(t);
1056                 if (dst_table == NULL)
1057                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1058                 else
1059                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1060                 if (tdt == NULL) {
1061                         if (dst_table)
1062                                 free(dst_table);
1063                         table_size = 0;
1064                 } else {
1065                         dst_table = tdt;
1066                         table_size++;
1067     
1068                         dst_table[i].zone = zone; 
1069                         dst_table[i].start = dst_table[i].end = t;
1070     
1071                         /* no entry will cover more than 6 months */
1072                         low = t - MAX_DST_WIDTH/2;
1073                         if (t < low)
1074                                 low = TIME_T_MIN;
1075       
1076                         high = t + MAX_DST_WIDTH/2;
1077                         if (high < t)
1078                                 high = TIME_T_MAX;
1079       
1080                         /*
1081                          * Widen the new entry using two bisection searches.
1082                          */
1083                         while (low+60*60 < dst_table[i].start) {
1084                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1085                                         t = dst_table[i].start - MAX_DST_SKIP;
1086                                 else
1087                                         t = low + (dst_table[i].start-low)/2;
1088                                 if (TimeZone(t) == zone)
1089                                         dst_table[i].start = t;
1090                                 else
1091                                         low = t;
1092                         }
1093
1094                         while (high-60*60 > dst_table[i].end) {
1095                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1096                                         t = dst_table[i].end + MAX_DST_SKIP;
1097                                 else
1098                                         t = high - (high-dst_table[i].end)/2;
1099                                 if (TimeZone(t) == zone)
1100                                         dst_table[i].end = t;
1101                                 else
1102                                         high = t;
1103                         }
1104                 }
1105         }
1106         return zone;
1107 }
1108
1109 /*
1110  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1111  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1112  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1113  * daylight savings transitions because some local times are ambiguous.
1114  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1115  */
1116 static int
1117 LocTimeDiff(time_t lt)
1118 {
1119         int d = TimeZoneFaster(lt);
1120         time_t t = lt + d;
1121
1122         /* if overflow occurred, ignore all the adjustments so far */
1123         if (((t < lt) ^ (d < 0)))
1124                 t = lt;
1125
1126         /*
1127          * Now t should be close enough to the true UTC to yield the
1128          * right answer.
1129          */
1130         return TimeZoneFaster(t);
1131 }
1132
1133 static int
1134 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1135 {
1136         guint32 timeval;
1137         nstime_t ts;
1138  
1139         timeval = tvb_get_letohl(tvb, offset);
1140         if (timeval == 0xffffffff) {
1141                 proto_tree_add_text(tree, tvb, offset, 4,
1142                     "%s: No time specified (0xffffffff)",
1143                     proto_registrar_get_name(hf_date));
1144                 offset += 4;
1145                 return offset;
1146         }
1147
1148         /*
1149          * We add the local time offset.
1150          */
1151         ts.secs = timeval + LocTimeDiff(timeval);
1152         ts.nsecs = 0;
1153
1154         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1155         offset += 4;
1156  
1157         return offset;
1158 }
1159
1160 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1161
1162 /*
1163  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1164  * to an "nstime_t".
1165  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1166  * midnight "UTC", in 100ns units.
1167  * Return TRUE if the conversion succeeds, FALSE otherwise.
1168  *
1169  * According to the Samba code, it appears to be kludge-GMT (at least for
1170  * file listings). This means it's the GMT you get by taking a local time
1171  * and adding the server time zone offset.  This is NOT the same as GMT in
1172  * some cases.   However, we don't know the server time zone, so we don't
1173  * do that adjustment.
1174  *
1175  * This code is based on the Samba code:
1176  *
1177  *      Unix SMB/Netbios implementation.
1178  *      Version 1.9.
1179  *      time handling functions
1180  *      Copyright (C) Andrew Tridgell 1992-1998
1181  */
1182 static gboolean
1183 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1184 {
1185         double d;
1186         /* The next two lines are a fix needed for the 
1187             broken SCO compiler. JRA. */
1188         time_t l_time_min = TIME_T_MIN;
1189         time_t l_time_max = TIME_T_MAX;
1190
1191         if (filetime_high == 0)
1192                 return FALSE;
1193
1194         /*
1195          * Get the time as a double, in seconds and fractional seconds.
1196          */
1197         d = ((double)filetime_high)*4.0*(double)(1<<30);
1198         d += filetime_low;
1199         d *= 1.0e-7;
1200  
1201         /* Now adjust by 369 years, to make the seconds since 1970. */
1202         d -= TIME_FIXUP_CONSTANT;
1203
1204         if (!(l_time_min <= d && d <= l_time_max))
1205                 return FALSE;
1206
1207         /*
1208          * Get the time as seconds and nanoseconds.
1209          */
1210         tv->secs = d;
1211         tv->nsecs = (d - tv->secs)*1000000000;
1212
1213         return TRUE;
1214 }
1215
1216 int
1217 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1218 {
1219         guint32 filetime_high, filetime_low;
1220         nstime_t ts;
1221
1222         /* XXX there seems also to be another special time value which is fairly common :
1223            0x40000000 00000000  
1224            the meaning of this one is yet unknown 
1225         */
1226         if (tree) {
1227                 filetime_low = tvb_get_letohl(tvb, offset);
1228                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1229                 if (filetime_low == 0 && filetime_high == 0) {
1230                         proto_tree_add_text(tree, tvb, offset, 8,
1231                             "%s: No time specified (0)",
1232                             proto_registrar_get_name(hf_date));
1233                 } else if(filetime_low==0 && filetime_high==0x80000000){
1234                         proto_tree_add_text(tree, tvb, offset, 8,
1235                             "%s: Infinity (relative time)",
1236                             proto_registrar_get_name(hf_date));
1237                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1238                         proto_tree_add_text(tree, tvb, offset, 8,
1239                             "%s: Infinity (absolute time)",
1240                             proto_registrar_get_name(hf_date));
1241                 } else {                        
1242                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1243                                 proto_tree_add_time(tree, hf_date, tvb,
1244                                     offset, 8, &ts);
1245                         } else {
1246                                 proto_tree_add_text(tree, tvb, offset, 8,
1247                                     "%s: Time can't be converted",
1248                                     proto_registrar_get_name(hf_date));
1249                         }
1250                 }
1251         }
1252
1253         offset += 8;
1254         return offset;
1255 }
1256
1257 static int
1258 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1259     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1260 {
1261         guint16 dos_time, dos_date;
1262         proto_item *item = NULL;
1263         proto_tree *tree = NULL;
1264         struct tm tm;
1265         time_t t;
1266         static const int mday_noleap[12] = {
1267                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1268         };
1269         static const int mday_leap[12] = {
1270                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1271         };
1272 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1273         nstime_t tv;
1274
1275         if (time_first) {
1276                 dos_time = tvb_get_letohs(tvb, offset);
1277                 dos_date = tvb_get_letohs(tvb, offset+2);
1278         } else {
1279                 dos_date = tvb_get_letohs(tvb, offset);
1280                 dos_time = tvb_get_letohs(tvb, offset+2);
1281         }
1282
1283         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1284             (dos_date == 0 && dos_time == 0)) {
1285                 /*
1286                  * No date/time specified.
1287                  */
1288                 if(parent_tree){
1289                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1290                             "%s: No time specified (0x%08x)",
1291                             proto_registrar_get_name(hf_date),
1292                             (dos_date << 16) | dos_time);
1293                 }
1294                 offset += 4;
1295                 return offset;
1296         }
1297
1298         tm.tm_sec = (dos_time&0x1f)*2;
1299         tm.tm_min = (dos_time>>5)&0x3f;
1300         tm.tm_hour = (dos_time>>11)&0x1f;
1301         tm.tm_mday = dos_date&0x1f;
1302         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1303         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1304         tm.tm_isdst = -1;
1305
1306         /*
1307          * Do some sanity checks before calling "mktime()";
1308          * "mktime()" doesn't do them, it "normalizes" out-of-range
1309          * values.
1310          */
1311         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1312            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1313            (ISLEAP(tm.tm_year + 1900) ?
1314              tm.tm_mday > mday_leap[tm.tm_mon] :
1315              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1316              (t = mktime(&tm)) == -1) {
1317                 /*
1318                  * Invalid date/time.
1319                  */
1320                 if (parent_tree) {
1321                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1322                             "%s: Invalid time",
1323                             proto_registrar_get_name(hf_date));
1324                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1325                         if (time_first) {
1326                                 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);
1327                                 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);
1328                         } else {
1329                                 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);
1330                                 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);
1331                         }
1332                 }
1333                 offset += 4;
1334                 return offset;
1335         }
1336
1337         tv.secs = t;
1338         tv.nsecs = 0;
1339
1340         if(parent_tree){
1341                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1342                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1343                 if (time_first) {
1344                         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);
1345                         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);
1346                 } else {
1347                         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);
1348                         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);
1349                 }
1350         }
1351
1352         offset += 4;
1353
1354         return offset;
1355 }
1356
1357
1358 static const value_string da_access_vals[] = {
1359         { 0,            "Open for reading"},
1360         { 1,            "Open for writing"},
1361         { 2,            "Open for reading and writing"},
1362         { 3,            "Open for execute"},
1363         {0, NULL}
1364 };
1365 static const value_string da_sharing_vals[] = {
1366         { 0,            "Compatibility mode"},
1367         { 1,            "Deny read/write/execute (exclusive)"},
1368         { 2,            "Deny write"},
1369         { 3,            "Deny read/execute"},
1370         { 4,            "Deny none"},
1371         {0, NULL}
1372 };
1373 static const value_string da_locality_vals[] = {
1374         { 0,            "Locality of reference unknown"},
1375         { 1,            "Mainly sequential access"},
1376         { 2,            "Mainly random access"},
1377         { 3,            "Random access with some locality"},
1378         {0, NULL}
1379 };
1380 static const true_false_string tfs_da_caching = {
1381         "Do not cache this file",
1382         "Caching permitted on this file"
1383 };
1384 static const true_false_string tfs_da_writetru = {
1385         "Write through enabled",
1386         "Write through disabled"
1387 };
1388 static int
1389 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1390 {
1391         guint16 mask;
1392         proto_item *item = NULL;
1393         proto_tree *tree = NULL;
1394
1395         mask = tvb_get_letohs(tvb, offset);
1396
1397         if(parent_tree){
1398                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1399                         "%s Access: 0x%04x", type, mask);
1400                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1401         }
1402
1403         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1404                 tvb, offset, 2, mask);
1405         proto_tree_add_boolean(tree, hf_smb_access_caching,
1406                 tvb, offset, 2, mask);
1407         proto_tree_add_uint(tree, hf_smb_access_locality,
1408                 tvb, offset, 2, mask);
1409         proto_tree_add_uint(tree, hf_smb_access_sharing,
1410                 tvb, offset, 2, mask);
1411         proto_tree_add_uint(tree, hf_smb_access_mode,
1412                 tvb, offset, 2, mask);
1413
1414         offset += 2;
1415
1416         return offset;
1417 }
1418
1419 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1420 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1421 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1422 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1423 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1424 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1425 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1426 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1427 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1428 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1429 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1430 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1431 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1432 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1433 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1434
1435 /*
1436  * These are flags to be used in NT Create operations.
1437  */
1438 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1439 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1440 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1441 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1442 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1443 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1444 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1445
1446 static const true_false_string tfs_file_attribute_write_through = {
1447         "This object requires WRITE THROUGH",
1448         "This object does NOT require write through",
1449 };
1450 static const true_false_string tfs_file_attribute_no_buffering = {
1451         "This object requires NO BUFFERING",
1452         "This object can be buffered",
1453 };
1454 static const true_false_string tfs_file_attribute_random_access = {
1455         "This object will be RANDOM ACCESSed",
1456         "Random access is NOT requested",
1457 };
1458 static const true_false_string tfs_file_attribute_sequential_scan = {
1459         "This object is optimized for SEQUENTIAL SCAN",
1460         "This object is NOT optimized for sequential scan",
1461 };
1462 static const true_false_string tfs_file_attribute_delete_on_close = {
1463         "This object will be DELETED ON CLOSE",
1464         "This object will not be deleted on close",
1465 };
1466 static const true_false_string tfs_file_attribute_backup_semantics = {
1467         "This object supports BACKUP SEMANTICS",
1468         "This object does NOT support backup semantics",
1469 };
1470 static const true_false_string tfs_file_attribute_posix_semantics = {
1471         "This object supports POSIX SEMANTICS",
1472         "This object does NOT support POSIX semantics",
1473 };
1474 static const true_false_string tfs_file_attribute_read_only = {
1475         "This file is READ ONLY",
1476         "This file is NOT read only",
1477 };
1478 static const true_false_string tfs_file_attribute_hidden = {
1479         "This is a HIDDEN file",
1480         "This is NOT a hidden file"
1481 };
1482 static const true_false_string tfs_file_attribute_system = {
1483         "This is a SYSTEM file",
1484         "This is NOT a system file"
1485 };
1486 static const true_false_string tfs_file_attribute_volume = {
1487         "This is a VOLUME ID",
1488         "This is NOT a volume ID"
1489 };
1490 static const true_false_string tfs_file_attribute_directory = {
1491         "This is a DIRECTORY",
1492         "This is NOT a directory"
1493 };
1494 static const true_false_string tfs_file_attribute_archive = {
1495         "This is an ARCHIVE file",
1496         "This is NOT an archive file"
1497 };
1498 static const true_false_string tfs_file_attribute_device = {
1499         "This is a DEVICE",
1500         "This is NOT a device"
1501 };
1502 static const true_false_string tfs_file_attribute_normal = {
1503         "This file is an ordinary file",
1504         "This file has some attribute set"
1505 };
1506 static const true_false_string tfs_file_attribute_temporary = {
1507         "This is a TEMPORARY file",
1508         "This is NOT a temporary file"
1509 };
1510 static const true_false_string tfs_file_attribute_sparse = {
1511         "This is a SPARSE file",
1512         "This is NOT a sparse file"
1513 };
1514 static const true_false_string tfs_file_attribute_reparse = {
1515         "This file has an associated REPARSE POINT",
1516         "This file does NOT have an associated reparse point"
1517 };
1518 static const true_false_string tfs_file_attribute_compressed = {
1519         "This is a COMPRESSED file",
1520         "This is NOT a compressed file"
1521 };
1522 static const true_false_string tfs_file_attribute_offline = {
1523         "This file is OFFLINE",
1524         "This file is NOT offline"
1525 };
1526 static const true_false_string tfs_file_attribute_not_content_indexed = {
1527         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1528         "This file MAY be indexed by the content indexing service"
1529 };
1530 static const true_false_string tfs_file_attribute_encrypted = {
1531         "This is an ENCRYPTED file",
1532         "This is NOT an encrypted file"
1533 };
1534
1535 static int
1536 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1537 {
1538         guint16 mask;
1539         proto_item *item = NULL;
1540         proto_tree *tree = NULL;
1541
1542         mask = tvb_get_letohs(tvb, offset);
1543
1544         if(parent_tree){
1545                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1546                         "File Attributes: 0x%04x", mask);
1547                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1548         }
1549         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1550                 tvb, offset, 2, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1552                 tvb, offset, 2, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1554                 tvb, offset, 2, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1556                 tvb, offset, 2, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1558                 tvb, offset, 2, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1560                 tvb, offset, 2, mask);
1561
1562         offset += 2;
1563
1564         return offset;
1565 }
1566
1567 /* 3.11 */
1568 static int
1569 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1570 {
1571         guint32 mask;
1572         proto_item *item = NULL;
1573         proto_tree *tree = NULL;
1574
1575         mask = tvb_get_letohl(tvb, offset);
1576
1577         if(parent_tree){
1578                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1579                         "File Attributes: 0x%08x", mask);
1580                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1581         }
1582
1583         /*
1584          * XXX - Network Monitor disagrees on some of the
1585          * bits, e.g. the bits above temporary are "atomic write"
1586          * and "transaction write", and it says nothing about the
1587          * bits above that.
1588          *
1589          * Does the Win32 API documentation, or the NT Native API book,
1590          * suggest anything?
1591          */
1592         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1593                 tvb, offset, 4, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1595                 tvb, offset, 4, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1597                 tvb, offset, 4, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1599                 tvb, offset, 4, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1601                 tvb, offset, 4, mask);
1602         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1603                 tvb, offset, 4, mask);
1604         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1605                 tvb, offset, 4, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1607                 tvb, offset, 4, mask);
1608         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1609                 tvb, offset, 4, mask);
1610         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1611                 tvb, offset, 4, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1613                 tvb, offset, 4, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1615                 tvb, offset, 4, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1617                 tvb, offset, 4, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1619                 tvb, offset, 4, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1621                 tvb, offset, 4, mask);
1622         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1623                 tvb, offset, 4, mask);
1624         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1625                 tvb, offset, 4, mask);
1626         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1627                 tvb, offset, 4, mask);
1628         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1629                 tvb, offset, 4, mask);
1630         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1631                 tvb, offset, 4, mask);
1632         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1633                 tvb, offset, 4, mask);
1634         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1635                 tvb, offset, 4, mask);
1636
1637         offset += 4;
1638
1639         return offset;
1640 }
1641
1642 static int
1643 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1644 {
1645         guint8 mask;
1646         proto_item *item = NULL;
1647         proto_tree *tree = NULL;
1648
1649         mask = tvb_get_guint8(tvb, offset);
1650
1651         if(parent_tree){
1652                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1653                         "File Attributes: 0x%02x", mask);
1654                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1655         }
1656         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1657                 tvb, offset, 1, mask);
1658         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1659                 tvb, offset, 1, mask);
1660         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1661                 tvb, offset, 1, mask);
1662         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1663                 tvb, offset, 1, mask);
1664         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1665                 tvb, offset, 1, mask);
1666         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1667                 tvb, offset, 1, mask);
1668
1669         offset += 1;
1670
1671         return offset;
1672 }
1673
1674 static const true_false_string tfs_search_attribute_read_only = {
1675         "Include READ ONLY files in search results",
1676         "Do NOT include read only files in search results",
1677 };
1678 static const true_false_string tfs_search_attribute_hidden = {
1679         "Include HIDDEN files in search results",
1680         "Do NOT include hidden files in search results"
1681 };
1682 static const true_false_string tfs_search_attribute_system = {
1683         "Include SYSTEM files in search results",
1684         "Do NOT include system files in search results"
1685 };
1686 static const true_false_string tfs_search_attribute_volume = {
1687         "Include VOLUME IDs in search results",
1688         "Do NOT include volume IDs in search results"
1689 };
1690 static const true_false_string tfs_search_attribute_directory = {
1691         "Include DIRECTORIES in search results",
1692         "Do NOT include directories in search results"
1693 };
1694 static const true_false_string tfs_search_attribute_archive = {
1695         "Include ARCHIVE files in search results",
1696         "Do NOT include archive files in search results"
1697 };
1698
1699 static int
1700 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1701 {
1702         guint16 mask;
1703         proto_item *item = NULL;
1704         proto_tree *tree = NULL;
1705
1706         mask = tvb_get_letohs(tvb, offset);
1707
1708         if(parent_tree){
1709                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1710                         "Search Attributes: 0x%04x", mask);
1711                 tree = proto_item_add_subtree(item, ett_smb_search);
1712         }
1713
1714         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1715                 tvb, offset, 2, mask);
1716         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1717                 tvb, offset, 2, mask);
1718         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1719                 tvb, offset, 2, mask);  
1720         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1721                 tvb, offset, 2, mask);
1722         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1723                 tvb, offset, 2, mask);
1724         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1725                 tvb, offset, 2, mask);
1726
1727         offset += 2;
1728         return offset;
1729 }
1730
1731 #if 0
1732 /*
1733  * XXX - this isn't used.
1734  * Is this used for anything?  NT Create AndX doesn't use it.
1735  * Is there some 16-bit attribute field with more bits than Read Only,
1736  * Hidden, System, Volume ID, Directory, and Archive?
1737  */
1738 static int
1739 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1740 {
1741         guint32 mask;
1742         proto_item *item = NULL;
1743         proto_tree *tree = NULL;
1744
1745         mask = tvb_get_letohl(tvb, offset);
1746
1747         if(parent_tree){
1748                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1749                         "File Attributes: 0x%08x", mask);
1750                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1751         }
1752         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1753                 tvb, offset, 2, mask);
1754         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1755                 tvb, offset, 2, mask);
1756         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1757                 tvb, offset, 2, mask);
1758         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1759                 tvb, offset, 2, mask);
1760         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1761                 tvb, offset, 2, mask);
1762         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1763                 tvb, offset, 2, mask);
1764         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1765                 tvb, offset, 2, mask);
1766         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1767                 tvb, offset, 2, mask);
1768         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1769                 tvb, offset, 2, mask);
1770         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1771                 tvb, offset, 2, mask);
1772         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1773                 tvb, offset, 2, mask);
1774         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1775                 tvb, offset, 2, mask);
1776         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1777                 tvb, offset, 2, mask);
1778         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1779                 tvb, offset, 2, mask);
1780         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1781                 tvb, offset, 2, mask);
1782
1783         offset += 2;
1784
1785         return offset;
1786 }
1787 #endif
1788
1789
1790 #define SERVER_CAP_RAW_MODE            0x00000001
1791 #define SERVER_CAP_MPX_MODE            0x00000002
1792 #define SERVER_CAP_UNICODE             0x00000004
1793 #define SERVER_CAP_LARGE_FILES         0x00000008
1794 #define SERVER_CAP_NT_SMBS             0x00000010
1795 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1796 #define SERVER_CAP_STATUS32            0x00000040
1797 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1798 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1799 #define SERVER_CAP_NT_FIND             0x00000200
1800 #define SERVER_CAP_DFS                 0x00001000
1801 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1802 #define SERVER_CAP_LARGE_READX         0x00004000
1803 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1804 #define SERVER_CAP_UNIX                0x00800000
1805 #define SERVER_CAP_RESERVED            0x02000000
1806 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1807 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1808 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1809 static const true_false_string tfs_server_cap_raw_mode = {
1810         "Read Raw and Write Raw are supported",
1811         "Read Raw and Write Raw are not supported"
1812 };
1813 static const true_false_string tfs_server_cap_mpx_mode = {
1814         "Read Mpx and Write Mpx are supported",
1815         "Read Mpx and Write Mpx are not supported"
1816 };
1817 static const true_false_string tfs_server_cap_unicode = {
1818         "Unicode strings are supported",
1819         "Unicode strings are not supported"
1820 };
1821 static const true_false_string tfs_server_cap_large_files = {
1822         "Large files are supported",
1823         "Large files are not supported",
1824 };
1825 static const true_false_string tfs_server_cap_nt_smbs = {
1826         "NT SMBs are supported",
1827         "NT SMBs are not supported"
1828 };
1829 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1830         "RPC remote APIs are supported",
1831         "RPC remote APIs are not supported"
1832 };
1833 static const true_false_string tfs_server_cap_nt_status = {
1834         "NT status codes are supported",
1835         "NT status codes are not supported"
1836 };
1837 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1838         "Level 2 oplocks are supported",
1839         "Level 2 oplocks are not supported"
1840 };
1841 static const true_false_string tfs_server_cap_lock_and_read = {
1842         "Lock and Read is supported",
1843         "Lock and Read is not supported"
1844 };
1845 static const true_false_string tfs_server_cap_nt_find = {
1846         "NT Find is supported",
1847         "NT Find is not supported"
1848 };
1849 static const true_false_string tfs_server_cap_dfs = {
1850         "Dfs is supported",
1851         "Dfs is not supported"
1852 };
1853 static const true_false_string tfs_server_cap_infolevel_passthru = {
1854         "NT information level request passthrough is supported",
1855         "NT information level request passthrough is not supported"
1856 };
1857 static const true_false_string tfs_server_cap_large_readx = {
1858         "Large Read andX is supported",
1859         "Large Read andX is not supported"
1860 };
1861 static const true_false_string tfs_server_cap_large_writex = {
1862         "Large Write andX is supported",
1863         "Large Write andX is not supported"
1864 };
1865 static const true_false_string tfs_server_cap_unix = {
1866         "UNIX extensions are supported",
1867         "UNIX extensions are not supported"
1868 };
1869 static const true_false_string tfs_server_cap_reserved = {
1870         "Reserved",
1871         "Reserved"
1872 };
1873 static const true_false_string tfs_server_cap_bulk_transfer = {
1874         "Bulk Read and Bulk Write are supported",
1875         "Bulk Read and Bulk Write are not supported"
1876 };
1877 static const true_false_string tfs_server_cap_compressed_data = {
1878         "Compressed data transfer is supported",
1879         "Compressed data transfer is not supported"
1880 };
1881 static const true_false_string tfs_server_cap_extended_security = {
1882         "Extended security exchanges are supported",
1883         "Extended security exchanges are not supported"
1884 };
1885 static int
1886 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1887 {
1888         guint32 mask;
1889         proto_item *item = NULL;
1890         proto_tree *tree = NULL;
1891
1892         mask = tvb_get_letohl(tvb, offset);
1893
1894         if(parent_tree){
1895                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1896                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1897         }
1898
1899         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1900                 tvb, offset, 4, mask);
1901         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1902                 tvb, offset, 4, mask);
1903         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1904                 tvb, offset, 4, mask);
1905         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1906                 tvb, offset, 4, mask);
1907         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1908                 tvb, offset, 4, mask);
1909         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1910                 tvb, offset, 4, mask);
1911         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1912                 tvb, offset, 4, mask);
1913         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1914                 tvb, offset, 4, mask);
1915         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1916                 tvb, offset, 4, mask);
1917         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1918                 tvb, offset, 4, mask);
1919         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1920                 tvb, offset, 4, mask);
1921         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1922                 tvb, offset, 4, mask);
1923         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1924                 tvb, offset, 4, mask);
1925         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1926                 tvb, offset, 4, mask);
1927         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1928                 tvb, offset, 4, mask);
1929         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1930                 tvb, offset, 4, mask);
1931         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1932                 tvb, offset, 4, mask);
1933         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1934                 tvb, offset, 4, mask);
1935         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1936                 tvb, offset, 4, mask);
1937
1938         return mask;
1939 }
1940
1941 #define RAWMODE_READ   0x01
1942 #define RAWMODE_WRITE  0x02
1943 static const true_false_string tfs_rm_read = {
1944         "Read Raw is supported",
1945         "Read Raw is not supported"
1946 };
1947 static const true_false_string tfs_rm_write = {
1948         "Write Raw is supported",
1949         "Write Raw is not supported"
1950 };
1951
1952 static int
1953 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1954 {
1955         guint16 mask;
1956         proto_item *item = NULL;
1957         proto_tree *tree = NULL;
1958
1959         mask = tvb_get_letohs(tvb, offset);
1960
1961         if(parent_tree){
1962                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1963                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1964         }
1965
1966         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1967         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1968
1969         offset += 2;
1970
1971         return offset;
1972 }
1973
1974 #define SECURITY_MODE_MODE             0x01
1975 #define SECURITY_MODE_PASSWORD         0x02
1976 #define SECURITY_MODE_SIGNATURES       0x04
1977 #define SECURITY_MODE_SIG_REQUIRED     0x08
1978 static const true_false_string tfs_sm_mode = {
1979         "USER security mode",
1980         "SHARE security mode"
1981 };
1982 static const true_false_string tfs_sm_password = {
1983         "ENCRYPTED password. Use challenge/response",
1984         "PLAINTEXT password"
1985 };
1986 static const true_false_string tfs_sm_signatures = {
1987         "Security signatures ENABLED",
1988         "Security signatures NOT enabled"
1989 };
1990 static const true_false_string tfs_sm_sig_required = {
1991         "Security signatures REQUIRED",
1992         "Security signatures NOT required"
1993 };
1994
1995 static int
1996 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1997 {
1998         guint16 mask = 0;
1999         proto_item *item = NULL;
2000         proto_tree *tree = NULL;
2001
2002         switch(wc){
2003         case 13:
2004                 mask = tvb_get_letohs(tvb, offset);
2005                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2006                                 "Security Mode: 0x%04x", mask);
2007                 tree = proto_item_add_subtree(item, ett_smb_mode);
2008                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2009                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2010                 offset += 2;
2011                 break;
2012
2013         case 17:
2014                 mask = tvb_get_guint8(tvb, offset);
2015                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2016                                 "Security Mode: 0x%02x", mask);
2017                 tree = proto_item_add_subtree(item, ett_smb_mode);
2018                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2019                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2020                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2021                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2022                 offset += 1;
2023                 break;
2024         }
2025
2026         return offset;
2027 }
2028
2029 static int
2030 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2031 {
2032         proto_item *it = NULL;
2033         proto_tree *tr = NULL;
2034         guint16 bc;
2035         guint8 wc;
2036
2037         WORD_COUNT;
2038
2039         BYTE_COUNT;
2040
2041         if(tree){
2042                 it = proto_tree_add_text(tree, tvb, offset, bc,
2043                                 "Requested Dialects");
2044                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2045         }
2046
2047         while(bc){
2048                 int len;
2049                 const guint8 *str;
2050                 proto_item *dit = NULL;
2051                 proto_tree *dtr = NULL;
2052
2053                 /* XXX - what if this runs past bc? */
2054                 len = tvb_strsize(tvb, offset+1);
2055                 str = tvb_get_ptr(tvb, offset+1, len);
2056
2057                 if(tr){
2058                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2059                                         "Dialect: %s", str);
2060                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2061                 }
2062
2063                 /* Buffer Format */
2064                 CHECK_BYTE_COUNT(1);
2065                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2066                         TRUE);
2067                 COUNT_BYTES(1);
2068
2069                 /*Dialect Name */
2070                 CHECK_BYTE_COUNT(len);
2071                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2072                         len, str);
2073                 COUNT_BYTES(len);
2074         }
2075
2076         END_OF_SMB
2077
2078         return offset;
2079 }
2080
2081 static int
2082 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2083 {
2084         guint8 wc;
2085         guint16 dialect;
2086         const char *dn;
2087         int dn_len;
2088         guint16 bc;
2089         guint16 ekl=0;
2090         guint32 caps=0;
2091         gint16 tz;
2092
2093         WORD_COUNT;
2094
2095         /* Dialect Index */
2096         dialect = tvb_get_letohs(tvb, offset);
2097         switch(wc){
2098         case 1:
2099                 if(dialect==0xffff){
2100                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2101                                 tvb, offset, 2, dialect,
2102                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2103                 } else {
2104                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2105                                 tvb, offset, 2, dialect);
2106                 }
2107                 break;
2108         case 13:
2109                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2110                         tvb, offset, 2, dialect,
2111                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2112                 break;
2113         case 17:
2114                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2115                         tvb, offset, 2, dialect,
2116                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2117                 break;
2118         default:
2119                 proto_tree_add_text(tree, tvb, offset, wc*2,
2120                         "Words for unknown response format");
2121                 offset += wc*2;
2122                 goto bytecount;
2123         }
2124         offset += 2;
2125
2126         switch(wc){
2127         case 13:
2128                 /* Security Mode */
2129                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2130
2131                 /* Maximum Transmit Buffer Size */
2132                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2133                         tvb, offset, 2, TRUE);
2134                 offset += 2;
2135
2136                 /* Maximum Multiplex Count */
2137                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2138                         tvb, offset, 2, TRUE);
2139                 offset += 2;
2140
2141                 /* Maximum Vcs Number */
2142                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2143                         tvb, offset, 2, TRUE);
2144                 offset += 2;
2145
2146                 /* raw mode */
2147                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2148
2149                 /* session key */
2150                 proto_tree_add_item(tree, hf_smb_session_key,
2151                         tvb, offset, 4, TRUE);
2152                 offset += 4;
2153
2154                 /* current time and date at server */
2155                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2156                     TRUE);
2157
2158                 /* time zone */
2159                 tz = tvb_get_letohs(tvb, offset);
2160                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2161                 offset += 2;
2162
2163                 /* encryption key length */
2164                 ekl = tvb_get_letohs(tvb, offset);
2165                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2166                 offset += 2;
2167
2168                 /* 2 reserved bytes */
2169                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2170                 offset += 2;
2171
2172                 break;
2173
2174         case 17:
2175                 /* Security Mode */
2176                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2177
2178                 /* Maximum Multiplex Count */
2179                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2180                         tvb, offset, 2, TRUE);
2181                 offset += 2;
2182
2183                 /* Maximum Vcs Number */
2184                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2185                         tvb, offset, 2, TRUE);
2186                 offset += 2;
2187
2188                 /* Maximum Transmit Buffer Size */
2189                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2190                         tvb, offset, 4, TRUE);
2191                 offset += 4;
2192
2193                 /* maximum raw buffer size */
2194                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2195                         tvb, offset, 4, TRUE);
2196                 offset += 4;
2197
2198                 /* session key */
2199                 proto_tree_add_item(tree, hf_smb_session_key,
2200                         tvb, offset, 4, TRUE);
2201                 offset += 4;
2202
2203                 /* server capabilities */
2204                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2205                 offset += 4;
2206
2207                 /* system time */
2208                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2209                                 hf_smb_system_time);
2210
2211                 /* time zone */
2212                 tz = tvb_get_letohs(tvb, offset);
2213                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2214                         tvb, offset, 2, tz,
2215                         "Server Time Zone: %d min from UTC", tz);
2216                 offset += 2;
2217
2218                 /* encryption key length */
2219                 ekl = tvb_get_guint8(tvb, offset);
2220                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2221                         tvb, offset, 1, ekl);
2222                 offset += 1;
2223
2224                 break;
2225         }
2226
2227         BYTE_COUNT;
2228
2229         switch(wc){
2230         case 13:
2231                 /* challenge/response encryption key */
2232                 if(ekl){
2233                         CHECK_BYTE_COUNT(ekl);
2234                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2235                         COUNT_BYTES(ekl);
2236                 }
2237
2238                 /*
2239                  * Primary domain.
2240                  *
2241                  * XXX - not present if negotiated dialect isn't
2242                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2243                  * have to see the request, or assume what dialect strings
2244                  * were sent, to determine that.
2245                  *
2246                  * Is this something other than a primary domain if the
2247                  * negotiated dialect is Windows for Workgroups 3.1a?
2248                  * It appears to be 8 bytes of binary data in at least
2249                  * one capture - is that an encryption key or something
2250                  * such as that?
2251                  */
2252                 dn = get_unicode_or_ascii_string(tvb, &offset,
2253                         pinfo, &dn_len, FALSE, FALSE, &bc);
2254                 if (dn == NULL)
2255                         goto endofcommand;
2256                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2257                         offset, dn_len,dn);
2258                 COUNT_BYTES(dn_len);
2259                 break;
2260
2261         case 17:
2262                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2263                         smb_info_t *si;
2264
2265                         /* challenge/response encryption key */
2266                         /* XXX - is this aligned on an even boundary? */
2267                         if(ekl){
2268                                 CHECK_BYTE_COUNT(ekl);
2269                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2270                                         tvb, offset, ekl, TRUE);
2271                                 COUNT_BYTES(ekl);
2272                         }
2273
2274                         /* domain */
2275                         /* this string is special, unicode is flagged in caps */
2276                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2277                         si = pinfo->private_data;
2278                         si->unicode = (caps&SERVER_CAP_UNICODE);
2279                         dn = get_unicode_or_ascii_string(tvb,
2280                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2281                                 &bc);
2282                         if (dn == NULL)
2283                                 goto endofcommand;
2284                         proto_tree_add_string(tree, hf_smb_primary_domain,
2285                                 tvb, offset, dn_len, dn);
2286                         COUNT_BYTES(dn_len);
2287                 } else {
2288                         /* guid */
2289                         /* XXX - show it in the standard Microsoft format
2290                            for GUIDs? */
2291                         CHECK_BYTE_COUNT(16);
2292                         proto_tree_add_item(tree, hf_smb_server_guid,
2293                                 tvb, offset, 16, TRUE);
2294                         COUNT_BYTES(16);
2295
2296                         /* security blob */
2297                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2298                            data structure, at least in NT 5.0-and-later
2299                            server replies? */
2300                         if(bc){
2301                                 proto_tree_add_item(tree, hf_smb_security_blob,
2302                                         tvb, offset, bc, TRUE);
2303                                 COUNT_BYTES(bc);
2304                         }
2305                 }
2306                 break;
2307         }
2308
2309         END_OF_SMB
2310
2311         return offset;
2312 }
2313
2314
2315 static int
2316 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2317 {
2318         int dn_len;
2319         const char *dn;
2320         guint8 wc;
2321         guint16 bc;
2322
2323         WORD_COUNT;
2324  
2325         BYTE_COUNT;
2326
2327         /* buffer format */
2328         CHECK_BYTE_COUNT(1);
2329         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2330         COUNT_BYTES(1);
2331
2332         /* dir name */
2333         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2334                 FALSE, FALSE, &bc);
2335         if (dn == NULL)
2336                 goto endofcommand;
2337         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2338                 dn);
2339         COUNT_BYTES(dn_len);
2340
2341         if (check_col(pinfo->cinfo, COL_INFO)) {
2342                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2343         }
2344
2345         END_OF_SMB
2346
2347         return offset;
2348 }
2349
2350 static int
2351 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2352 {
2353         guint8 wc;
2354         guint16 bc;
2355  
2356         WORD_COUNT;
2357  
2358         BYTE_COUNT;
2359
2360         END_OF_SMB
2361
2362         return offset;
2363 }
2364
2365 static int
2366 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2367 {
2368         guint16 ec, bc;
2369         guint8 wc;
2370
2371         WORD_COUNT;
2372
2373         /* echo count */
2374         ec = tvb_get_letohs(tvb, offset);
2375         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2376         offset += 2;
2377
2378         BYTE_COUNT;
2379
2380         if (bc != 0) {
2381                 /* echo data */
2382                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2383                 COUNT_BYTES(bc);
2384         }
2385
2386         END_OF_SMB
2387
2388         return offset;
2389 }
2390
2391 static int
2392 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2393 {
2394         guint16 bc;
2395         guint8 wc;
2396
2397         WORD_COUNT;
2398
2399         /* echo sequence number */
2400         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2401         offset += 2;
2402
2403         BYTE_COUNT;
2404
2405         if (bc != 0) {
2406                 /* echo data */
2407                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2408                 COUNT_BYTES(bc);
2409         }
2410
2411         END_OF_SMB
2412
2413         return offset;
2414 }
2415
2416 static int
2417 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2418 {
2419         int an_len, pwlen;
2420         const char *an;
2421         guint8 wc;
2422         guint16 bc;
2423
2424         WORD_COUNT;
2425  
2426         BYTE_COUNT;
2427
2428         /* buffer format */
2429         CHECK_BYTE_COUNT(1);
2430         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2431         COUNT_BYTES(1);
2432
2433         /* Path */
2434         an = get_unicode_or_ascii_string(tvb, &offset,
2435                 pinfo, &an_len, FALSE, FALSE, &bc);
2436         if (an == NULL)
2437                 goto endofcommand;
2438         proto_tree_add_string(tree, hf_smb_path, tvb,
2439                 offset, an_len, an);
2440         COUNT_BYTES(an_len);
2441
2442         if (check_col(pinfo->cinfo, COL_INFO)) {
2443                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2444         }
2445
2446         /* buffer format */
2447         CHECK_BYTE_COUNT(1);
2448         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2449         COUNT_BYTES(1);
2450
2451         /* password, ANSI */
2452         /* XXX - what if this runs past bc? */
2453         pwlen = tvb_strsize(tvb, offset);
2454         CHECK_BYTE_COUNT(pwlen);
2455         proto_tree_add_item(tree, hf_smb_password,
2456                 tvb, offset, pwlen, TRUE);
2457         COUNT_BYTES(pwlen);
2458
2459         /* buffer format */
2460         CHECK_BYTE_COUNT(1);
2461         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2462         COUNT_BYTES(1);
2463
2464         /* Service */
2465         an = get_unicode_or_ascii_string(tvb, &offset,
2466                 pinfo, &an_len, FALSE, FALSE, &bc);
2467         if (an == NULL)
2468                 goto endofcommand;
2469         proto_tree_add_string(tree, hf_smb_service, tvb,
2470                 offset, an_len, an);
2471         COUNT_BYTES(an_len);
2472
2473         END_OF_SMB
2474
2475         return offset;
2476 }
2477
2478 static int
2479 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2480 {
2481         guint8 wc;
2482         guint16 bc;
2483
2484         WORD_COUNT;
2485  
2486         /* Maximum Buffer Size */
2487         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2488         offset += 2;
2489
2490         /* tid */
2491         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2492         offset += 2;
2493
2494         BYTE_COUNT;
2495
2496         END_OF_SMB
2497
2498         return offset;
2499 }
2500  
2501
2502 static const true_false_string tfs_of_create = {
2503         "Create file if it does not exist",
2504         "Fail if file does not exist"
2505 };
2506 static const value_string of_open[] = {
2507         { 0,            "Fail if file exists"},
2508         { 1,            "Open file if it exists"},
2509         { 2,            "Truncate file if it exists"},
2510         {0, NULL}
2511 };
2512 static int
2513 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2514 {
2515         guint16 mask;
2516         proto_item *item = NULL;
2517         proto_tree *tree = NULL;
2518
2519         mask = tvb_get_letohs(tvb, offset);
2520
2521         if(parent_tree){
2522                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2523                         "Open Function: 0x%04x", mask);
2524                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2525         }
2526
2527         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2528                 tvb, offset, 2, mask);
2529         proto_tree_add_uint(tree, hf_smb_open_function_open,
2530                 tvb, offset, 2, mask);
2531
2532         offset += 2;
2533
2534         return offset;
2535 }
2536
2537
2538 static const true_false_string tfs_mf_file = {
2539         "Target must be a file",
2540         "Target needn't be a file"
2541 };
2542 static const true_false_string tfs_mf_dir = {
2543         "Target must be a directory",
2544         "Target needn't be a directory"
2545 };
2546 static const true_false_string tfs_mf_verify = {
2547         "MUST verify all writes",
2548         "Don't have to verify writes"
2549 };
2550 static int
2551 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2552 {
2553         guint16 mask;
2554         proto_item *item = NULL;
2555         proto_tree *tree = NULL;
2556
2557         mask = tvb_get_letohs(tvb, offset);
2558
2559         if(parent_tree){
2560                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2561                         "Flags: 0x%04x", mask);
2562                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2563         }
2564  
2565         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2566                 tvb, offset, 2, mask);
2567         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2568                 tvb, offset, 2, mask);
2569         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2570                 tvb, offset, 2, mask);
2571
2572         offset += 2;
2573
2574         return offset;
2575 }
2576
2577 static const true_false_string tfs_cf_mode = {
2578         "ASCII",
2579         "Binary"
2580 };
2581 static const true_false_string tfs_cf_tree_copy = {
2582         "Copy is a tree copy",
2583         "Copy is a file copy"
2584 };
2585 static const true_false_string tfs_cf_ea_action = {
2586         "Fail copy",
2587         "Discard EAs"
2588 };
2589 static int
2590 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2591 {
2592         guint16 mask;
2593         proto_item *item = NULL;
2594         proto_tree *tree = NULL;
2595
2596         mask = tvb_get_letohs(tvb, offset);
2597
2598         if(parent_tree){
2599                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2600                         "Flags: 0x%04x", mask);
2601                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2602         }
2603  
2604         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2605                 tvb, offset, 2, mask);
2606         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2607                 tvb, offset, 2, mask);
2608         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2609                 tvb, offset, 2, mask);
2610         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2611                 tvb, offset, 2, mask);
2612         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2613                 tvb, offset, 2, mask);
2614         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2615                 tvb, offset, 2, mask);
2616         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2617                 tvb, offset, 2, mask);
2618
2619         offset += 2;
2620
2621         return offset;
2622 }
2623
2624 static int
2625 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2626 {
2627         int fn_len;
2628         guint16 tid;
2629         guint16 bc;
2630         guint8 wc;
2631         const char *fn;
2632
2633         WORD_COUNT;
2634
2635         /* tid */
2636         tid = tvb_get_letohs(tvb, offset);
2637         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2638                 "TID (target): 0x%04x", tid);
2639         offset += 2;
2640
2641         /* open function */
2642         offset = dissect_open_function(tvb, tree, offset);
2643
2644         /* move flags */
2645         offset = dissect_move_flags(tvb, tree, offset);
2646
2647         BYTE_COUNT;
2648
2649         /* buffer format */
2650         CHECK_BYTE_COUNT(1);
2651         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2652         COUNT_BYTES(1);
2653
2654         /* file name */
2655         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2656                 FALSE, FALSE, &bc);
2657         if (fn == NULL)
2658                 goto endofcommand;
2659         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2660                 fn_len, fn, "Old File Name: %s", fn);
2661         COUNT_BYTES(fn_len);
2662
2663         if (check_col(pinfo->cinfo, COL_INFO)) {
2664                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2665         }
2666
2667         /* buffer format */
2668         CHECK_BYTE_COUNT(1);
2669         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2670         COUNT_BYTES(1);
2671
2672         /* file name */
2673         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2674                 FALSE, FALSE, &bc);
2675         if (fn == NULL)
2676                 goto endofcommand;
2677         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2678                 fn_len, fn, "New File Name: %s", fn);
2679         COUNT_BYTES(fn_len);
2680
2681         if (check_col(pinfo->cinfo, COL_INFO)) {
2682                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2683         }
2684
2685         END_OF_SMB
2686
2687         return offset;
2688 }
2689
2690 static int
2691 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2692 {
2693         int fn_len;
2694         guint16 tid;
2695         guint16 bc;
2696         guint8 wc;
2697         const char *fn;
2698
2699         WORD_COUNT;
2700
2701         /* tid */
2702         tid = tvb_get_letohs(tvb, offset);
2703         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2704                 "TID (target): 0x%04x", tid);
2705         offset += 2;
2706
2707         /* open function */
2708         offset = dissect_open_function(tvb, tree, offset);
2709
2710         /* copy flags */
2711         offset = dissect_copy_flags(tvb, tree, offset);
2712
2713         BYTE_COUNT;
2714
2715         /* buffer format */
2716         CHECK_BYTE_COUNT(1);
2717         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2718         COUNT_BYTES(1);
2719
2720         /* file name */
2721         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2722                 FALSE, FALSE, &bc);
2723         if (fn == NULL)
2724                 goto endofcommand;
2725         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2726                 fn_len, fn, "Source File Name: %s", fn);
2727         COUNT_BYTES(fn_len);
2728
2729         if (check_col(pinfo->cinfo, COL_INFO)) {
2730                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2731         }
2732
2733         /* buffer format */
2734         CHECK_BYTE_COUNT(1);
2735         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2736         COUNT_BYTES(1);
2737
2738         /* file name */
2739         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2740                 FALSE, FALSE, &bc);
2741         if (fn == NULL)
2742                 goto endofcommand;
2743         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2744                 fn_len, fn, "Destination File Name: %s", fn);
2745         COUNT_BYTES(fn_len);
2746
2747         if (check_col(pinfo->cinfo, COL_INFO)) {
2748                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", 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 _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2758 {
2759         int fn_len;
2760         const char *fn;
2761         guint8 wc;
2762         guint16 bc;
2763
2764         WORD_COUNT;
2765
2766         /* # of files moved */
2767         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2768         offset += 2;
2769
2770         BYTE_COUNT;
2771
2772         /* buffer format */
2773         CHECK_BYTE_COUNT(1);
2774         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2775         COUNT_BYTES(1);
2776
2777         /* file name */
2778         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2779                 FALSE, FALSE, &bc);
2780         if (fn == NULL)
2781                 goto endofcommand;
2782         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2783                 fn);
2784         COUNT_BYTES(fn_len);
2785
2786         END_OF_SMB
2787
2788         return offset;
2789 }
2790
2791 static int
2792 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2793 {
2794         int fn_len;
2795         const char *fn;
2796         guint8 wc;
2797         guint16 bc;
2798
2799         WORD_COUNT;
2800
2801         /* desired access */
2802         offset = dissect_access(tvb, tree, offset, "Desired");
2803
2804         /* Search Attributes */
2805         offset = dissect_search_attributes(tvb, tree, offset);
2806
2807         BYTE_COUNT;
2808
2809         /* buffer format */
2810         CHECK_BYTE_COUNT(1);
2811         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2812         COUNT_BYTES(1);
2813
2814         /* file name */
2815         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2816                 FALSE, FALSE, &bc);
2817         if (fn == NULL)
2818                 goto endofcommand;
2819         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2820                 fn);
2821         COUNT_BYTES(fn_len);
2822
2823         if (check_col(pinfo->cinfo, COL_INFO)) {
2824                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2825         }
2826
2827         END_OF_SMB
2828
2829         return offset;
2830 }
2831
2832 void
2833 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2834     int len, guint16 fid)
2835 {
2836         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2837         if (check_col(pinfo->cinfo, COL_INFO))
2838                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2839 }
2840
2841 static int
2842 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2843 {
2844         guint8 wc;
2845         guint16 bc;
2846         guint16 fid;
2847
2848         WORD_COUNT;
2849
2850         /* fid */
2851         fid = tvb_get_letohs(tvb, offset);
2852         add_fid(tvb, pinfo, tree, offset, 2, fid);
2853         offset += 2;
2854
2855         /* File Attributes */
2856         offset = dissect_file_attributes(tvb, tree, offset);
2857
2858         /* last write time */
2859         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2860         
2861         /* File Size */
2862         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2863         offset += 4;
2864
2865         /* granted access */
2866         offset = dissect_access(tvb, tree, offset, "Granted");
2867
2868         BYTE_COUNT;
2869
2870         END_OF_SMB
2871
2872         return offset;
2873 }
2874
2875 static int
2876 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2877 {
2878         guint8 wc;
2879         guint16 bc;
2880         guint16 fid;
2881
2882         WORD_COUNT;
2883
2884         /* fid */
2885         fid = tvb_get_letohs(tvb, offset);
2886         add_fid(tvb, pinfo, tree, offset, 2, fid);
2887         offset += 2;
2888
2889         BYTE_COUNT;
2890
2891         END_OF_SMB
2892
2893         return offset;
2894 }
2895
2896 static int
2897 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2898 {
2899         int fn_len;
2900         const char *fn;
2901         guint8 wc;
2902         guint16 bc;
2903
2904         WORD_COUNT;
2905
2906         /* file attributes */
2907         offset = dissect_file_attributes(tvb, tree, offset);
2908
2909         /* creation time */
2910         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2911
2912         BYTE_COUNT;
2913
2914         /* buffer format */
2915         CHECK_BYTE_COUNT(1);
2916         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2917         COUNT_BYTES(1);
2918
2919         /* File Name */
2920         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2921                 FALSE, FALSE, &bc);
2922         if (fn == NULL)
2923                 goto endofcommand;
2924         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2925                 fn);
2926         COUNT_BYTES(fn_len);
2927
2928         if (check_col(pinfo->cinfo, COL_INFO)) {
2929                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2930         }
2931
2932         END_OF_SMB
2933
2934         return offset;
2935 }
2936
2937 static int
2938 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2939 {
2940         guint8 wc;
2941         guint16 bc, fid;
2942
2943         WORD_COUNT;
2944
2945         /* fid */
2946         fid = tvb_get_letohs(tvb, offset);
2947         add_fid(tvb, pinfo, tree, offset, 2, fid);
2948         offset += 2;
2949
2950         /* last write time */
2951         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2952
2953         BYTE_COUNT;
2954
2955         END_OF_SMB
2956
2957         return offset;
2958 }
2959
2960 static int
2961 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2962 {
2963         int fn_len;
2964         const char *fn;
2965         guint8 wc;
2966         guint16 bc;
2967
2968         WORD_COUNT;
2969
2970         /* search attributes */
2971         offset = dissect_search_attributes(tvb, tree, offset);
2972
2973         BYTE_COUNT;
2974
2975         /* buffer format */
2976         CHECK_BYTE_COUNT(1);
2977         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2978         COUNT_BYTES(1);
2979
2980         /* file name */
2981         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2982                 FALSE, FALSE, &bc);
2983         if (fn == NULL)
2984                 goto endofcommand;
2985         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2986                 fn);
2987         COUNT_BYTES(fn_len);
2988
2989         if (check_col(pinfo->cinfo, COL_INFO)) {
2990                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2991         }
2992
2993         END_OF_SMB
2994
2995         return offset;
2996 }
2997
2998 static int
2999 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3000 {
3001         int fn_len;
3002         const char *fn;
3003         guint8 wc;
3004         guint16 bc;
3005
3006         WORD_COUNT;
3007
3008         /* search attributes */
3009         offset = dissect_search_attributes(tvb, tree, offset);
3010
3011         BYTE_COUNT;
3012
3013         /* buffer format */
3014         CHECK_BYTE_COUNT(1);
3015         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3016         COUNT_BYTES(1);
3017
3018         /* old file name */
3019         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3020                 FALSE, FALSE, &bc);
3021         if (fn == NULL)
3022                 goto endofcommand;
3023         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3024                 fn);
3025         COUNT_BYTES(fn_len);
3026
3027         if (check_col(pinfo->cinfo, COL_INFO)) {
3028                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3029         }
3030
3031         /* buffer format */
3032         CHECK_BYTE_COUNT(1);
3033         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3034         COUNT_BYTES(1);
3035
3036         /* file name */
3037         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3038                 FALSE, FALSE, &bc);
3039         if (fn == NULL)
3040                 goto endofcommand;
3041         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3042                 fn);
3043         COUNT_BYTES(fn_len);
3044
3045         if (check_col(pinfo->cinfo, COL_INFO)) {
3046                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3047         }
3048
3049         END_OF_SMB
3050
3051         return offset;
3052 }
3053
3054 static int
3055 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3056 {
3057         int fn_len;
3058         const char *fn;
3059         guint8 wc;
3060         guint16 bc;
3061
3062         WORD_COUNT;
3063
3064         /* search attributes */
3065         offset = dissect_search_attributes(tvb, tree, offset);
3066  
3067         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3068         offset += 2;
3069
3070         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3071         offset += 4;
3072
3073         BYTE_COUNT;
3074
3075         /* buffer format */
3076         CHECK_BYTE_COUNT(1);
3077         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3078         COUNT_BYTES(1);
3079
3080         /* old file name */
3081         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3082                 FALSE, FALSE, &bc);
3083         if (fn == NULL)
3084                 goto endofcommand;
3085         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3086                 fn);
3087         COUNT_BYTES(fn_len);
3088
3089         if (check_col(pinfo->cinfo, COL_INFO)) {
3090                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3091         }
3092
3093         /* buffer format */
3094         CHECK_BYTE_COUNT(1);
3095         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3096         COUNT_BYTES(1);
3097
3098         /* file name */
3099         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3100                 FALSE, FALSE, &bc);
3101         if (fn == NULL)
3102                 goto endofcommand;
3103         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3104                 fn);
3105         COUNT_BYTES(fn_len);
3106
3107         if (check_col(pinfo->cinfo, COL_INFO)) {
3108                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3109         }
3110
3111         END_OF_SMB
3112
3113         return offset;
3114 }
3115
3116
3117 static int
3118 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3119 {
3120         guint16 bc;
3121         guint8 wc;
3122         const char *fn;
3123         int fn_len;
3124
3125         WORD_COUNT;
3126
3127         BYTE_COUNT;
3128
3129         /* Buffer Format */
3130         CHECK_BYTE_COUNT(1);
3131         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3132         COUNT_BYTES(1);
3133
3134         /* File Name */
3135         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3136                 FALSE, FALSE, &bc);
3137         if (fn == NULL)
3138                 goto endofcommand;
3139         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3140                 fn);
3141         COUNT_BYTES(fn_len);
3142
3143         if (check_col(pinfo->cinfo, COL_INFO)) {
3144                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3145         }
3146
3147         END_OF_SMB
3148
3149         return offset;
3150 }
3151  
3152 static int
3153 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3154 {
3155         guint16 bc;
3156         guint8 wc;
3157
3158         WORD_COUNT;
3159
3160         /* File Attributes */
3161         offset = dissect_file_attributes(tvb, tree, offset);
3162
3163         /* Last Write Time */
3164         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3165
3166         /* File Size */
3167         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3168         offset += 4;
3169
3170         /* 10 reserved bytes */
3171         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3172         offset += 10;
3173
3174         BYTE_COUNT;
3175
3176         END_OF_SMB
3177
3178         return offset;
3179 }
3180
3181 static int
3182 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3183 {
3184         int fn_len;
3185         const char *fn;
3186         guint8 wc;
3187         guint16 bc;
3188
3189         WORD_COUNT;
3190
3191         /* file attributes */
3192         offset = dissect_file_attributes(tvb, tree, offset);
3193
3194         /* last write time */
3195         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3196
3197         /* 10 reserved bytes */
3198         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3199         offset += 10;
3200
3201         BYTE_COUNT;
3202
3203         /* buffer format */
3204         CHECK_BYTE_COUNT(1);
3205         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3206         COUNT_BYTES(1);
3207
3208         /* file name */
3209         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3210                 FALSE, FALSE, &bc);
3211         if (fn == NULL)
3212                 goto endofcommand;
3213         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3214                 fn);
3215         COUNT_BYTES(fn_len);
3216
3217         if (check_col(pinfo->cinfo, COL_INFO)) {
3218                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3219         }
3220
3221         END_OF_SMB
3222
3223         return offset;
3224 }
3225
3226 static int
3227 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3228 {
3229         guint8 wc;
3230         guint16 bc;
3231         smb_info_t *si;
3232         unsigned int fid;
3233
3234         WORD_COUNT;
3235
3236         /* fid */
3237         fid = tvb_get_letohs(tvb, offset);
3238         add_fid(tvb, pinfo, tree, offset, 2, fid);
3239         offset += 2;
3240         if (!pinfo->fd->flags.visited) {
3241                 /* remember the FID for the processing of the response */
3242                 si = (smb_info_t *)pinfo->private_data;
3243                 si->sip->extra_info=(void *)fid;
3244         }
3245
3246         /* read count */
3247         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3248         offset += 2;
3249
3250         /* offset */
3251         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3252         offset += 4;
3253
3254         /* remaining */
3255         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3256         offset += 2;
3257
3258         BYTE_COUNT;
3259
3260         END_OF_SMB
3261
3262         return offset;
3263 }
3264
3265 int
3266 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3267 {
3268         int tvblen;
3269
3270         if(bc>datalen){
3271                 /* We have some initial padding bytes. */
3272                 /* XXX - use the data offset here instead? */
3273                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3274                         TRUE);
3275                 offset += bc-datalen;
3276                 bc = datalen;
3277         }
3278         tvblen = tvb_length_remaining(tvb, offset);
3279         if(bc>tvblen){
3280                 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);
3281                 offset += tvblen;
3282         } else {
3283                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3284                 offset += bc;
3285         }
3286         return offset;
3287 }
3288
3289 static int
3290 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3291     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3292 {
3293         int tvblen;
3294         tvbuff_t *dcerpc_tvb;
3295
3296         if(bc>datalen){
3297                 /* We have some initial padding bytes. */
3298                 /* XXX - use the data offset here instead? */
3299                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3300                         TRUE);
3301                 offset += bc-datalen;
3302                 bc = datalen;
3303         }
3304         tvblen = tvb_length_remaining(tvb, offset);
3305         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3306         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3307         if(bc>tvblen)
3308                 offset += tvblen;
3309         else
3310                 offset += bc;
3311         return offset;
3312 }
3313
3314 static int
3315 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3316 {
3317         guint16 cnt=0, bc;
3318         guint8 wc;
3319         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3320         int fid=0;
3321
3322         WORD_COUNT;
3323
3324         /* read count */
3325         cnt = tvb_get_letohs(tvb, offset);
3326         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3327         offset += 2;
3328
3329         /* 8 reserved bytes */
3330         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3331         offset += 8;
3332
3333         /* If we have seen the request, then print which FID this refers to */
3334         /* first check if we have seen the request */
3335         if(si->sip != NULL && si->sip->frame_req>0){
3336                 fid=(int)si->sip->extra_info;
3337                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3338         }
3339
3340         BYTE_COUNT;
3341
3342         /* buffer format */
3343         CHECK_BYTE_COUNT(1);
3344         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3345         COUNT_BYTES(1);
3346
3347         /* data len */
3348         CHECK_BYTE_COUNT(2);
3349         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3350         COUNT_BYTES(2);
3351
3352         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3353            read write */
3354         if(bc){
3355                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3356                         /* dcerpc call */
3357                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3358                             top_tree, offset, bc, bc, fid);
3359                 } else {
3360                         /* ordinary file data, or we didn't see the request,
3361                            so we don't know whether this is a DCERPC call
3362                            or not */
3363                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3364                 }
3365                 bc = 0;
3366         }
3367
3368         END_OF_SMB
3369
3370         return offset;
3371 }
3372
3373 static int
3374 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3375 {
3376         guint16 cnt, bc;
3377         guint8 wc;
3378
3379         WORD_COUNT;
3380
3381         /* read count */
3382         cnt = tvb_get_letohs(tvb, offset);
3383         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3384         offset += 2;
3385
3386         /* 8 reserved bytes */
3387         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3388         offset += 8;
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         END_OF_SMB
3403
3404         return offset;
3405 }
3406
3407
3408 static int
3409 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3410 {
3411         guint32 ofs=0;
3412         guint16 cnt=0, bc, fid=0;
3413         guint8 wc;
3414         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3415
3416         WORD_COUNT;
3417
3418         /* fid */
3419         fid = tvb_get_letohs(tvb, offset);
3420         add_fid(tvb, pinfo, tree, offset, 2, fid);
3421         offset += 2;
3422
3423         /* write count */
3424         cnt = tvb_get_letohs(tvb, offset);
3425         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3426         offset += 2;
3427
3428         /* offset */
3429         ofs = tvb_get_letohl(tvb, offset);
3430         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3431         offset += 4;
3432
3433         if (check_col(pinfo->cinfo, COL_INFO))
3434                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3435                                 ", %u byte%s at offset %u", cnt, 
3436                                 (cnt == 1) ? "" : "s", ofs);
3437
3438         /* remaining */
3439         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3440         offset += 2;
3441
3442         BYTE_COUNT;
3443
3444         /* buffer format */
3445         CHECK_BYTE_COUNT(1);
3446         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3447         COUNT_BYTES(1);
3448
3449         /* data len */
3450         CHECK_BYTE_COUNT(2);
3451         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3452         COUNT_BYTES(2);
3453
3454         if (bc != 0) {
3455                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3456                         /* dcerpc call */
3457                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3458                             top_tree, offset, bc, bc, fid);
3459                 } else {
3460                         /* ordinary file data */
3461                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3462                 }
3463                 bc = 0;
3464         }
3465
3466         END_OF_SMB
3467
3468         return offset;
3469 }
3470  
3471 static int
3472 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3473 {
3474         guint8 wc;
3475         guint16 bc, cnt;
3476
3477         WORD_COUNT;
3478
3479         /* write count */
3480         cnt = tvb_get_letohs(tvb, offset);
3481         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3482         offset += 2;
3483
3484         if (check_col(pinfo->cinfo, COL_INFO))
3485                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3486                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3487
3488         BYTE_COUNT;
3489
3490         END_OF_SMB
3491
3492         return offset;
3493 }
3494
3495 static int
3496 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3497 {
3498         guint8 wc;
3499         guint16 bc, fid;
3500
3501         WORD_COUNT;
3502
3503         /* fid */
3504         fid = tvb_get_letohs(tvb, offset);
3505         add_fid(tvb, pinfo, tree, offset, 2, fid);
3506         offset += 2;
3507
3508         /* lock count */
3509         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3510         offset += 4;
3511
3512         /* offset */
3513         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3514         offset += 4;
3515
3516         BYTE_COUNT;
3517
3518         END_OF_SMB
3519
3520         return offset;
3521 }
3522
3523 static int
3524 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3525 {
3526         int fn_len;
3527         const char *fn;
3528         guint8 wc;
3529         guint16 bc;
3530
3531         WORD_COUNT;
3532
3533         /* 2 reserved bytes */
3534         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3535         offset += 2;
3536
3537         /* Creation time */
3538         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3539
3540         BYTE_COUNT;
3541
3542         /* buffer format */
3543         CHECK_BYTE_COUNT(1);
3544         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3545         COUNT_BYTES(1);
3546
3547         /* directory name */
3548         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3549                 FALSE, FALSE, &bc);
3550         if (fn == NULL)
3551                 goto endofcommand;
3552         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3553                 fn);
3554         COUNT_BYTES(fn_len);
3555
3556         if (check_col(pinfo->cinfo, COL_INFO)) {
3557                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3558         }
3559
3560         END_OF_SMB
3561
3562         return offset;
3563 }
3564
3565 static int
3566 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3567 {
3568         int fn_len;
3569         const char *fn;
3570         guint8 wc;
3571         guint16 bc, fid;
3572
3573         WORD_COUNT;
3574
3575         /* fid */
3576         fid = tvb_get_letohs(tvb, offset);
3577         add_fid(tvb, pinfo, tree, offset, 2, fid);
3578         offset += 2;
3579
3580         BYTE_COUNT;
3581
3582         /* buffer format */
3583         CHECK_BYTE_COUNT(1);
3584         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3585         COUNT_BYTES(1);
3586
3587         /* file name */
3588         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3589                 FALSE, FALSE, &bc);
3590         if (fn == NULL)
3591                 goto endofcommand;
3592         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3593                 fn);
3594         COUNT_BYTES(fn_len);
3595
3596         END_OF_SMB
3597
3598         return offset;
3599 }
3600
3601 static const value_string seek_mode_vals[] = {
3602         {0,     "From Start Of File"},
3603         {1,     "From Current Position"},
3604         {2,     "From End Of File"},
3605         {0,     NULL}
3606 };
3607
3608 static int
3609 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3610 {
3611         guint8 wc;
3612         guint16 bc, fid;
3613
3614         WORD_COUNT;
3615
3616         /* fid */
3617         fid = tvb_get_letohs(tvb, offset);
3618         add_fid(tvb, pinfo, tree, offset, 2, fid);
3619         offset += 2;
3620
3621         /* Seek Mode */
3622         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3623         offset += 2;
3624
3625         /* offset */
3626         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3627         offset += 4;
3628
3629         BYTE_COUNT;
3630
3631         END_OF_SMB
3632
3633         return offset;
3634 }
3635
3636 static int
3637 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3638 {
3639         guint8 wc;
3640         guint16 bc;
3641
3642         WORD_COUNT;
3643
3644         /* offset */
3645         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3646         offset += 4;
3647
3648         BYTE_COUNT;
3649
3650         END_OF_SMB
3651
3652         return offset;
3653 }
3654  
3655 static int
3656 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3657 {
3658         guint8 wc;
3659         guint16 bc, fid;
3660
3661         WORD_COUNT;
3662
3663         /* fid */
3664         fid = tvb_get_letohs(tvb, offset);
3665         add_fid(tvb, pinfo, tree, offset, 2, fid);
3666         offset += 2;
3667
3668         /* create time */
3669         offset = dissect_smb_datetime(tvb, tree, offset,
3670                 hf_smb_create_time,
3671                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3672
3673         /* access time */
3674         offset = dissect_smb_datetime(tvb, tree, offset,
3675                 hf_smb_access_time,
3676                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3677
3678         /* last write time */
3679         offset = dissect_smb_datetime(tvb, tree, offset,
3680                 hf_smb_last_write_time,
3681                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3682
3683         BYTE_COUNT;
3684
3685         END_OF_SMB
3686
3687         return offset;
3688 }
3689
3690 static int
3691 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3692 {
3693         guint8 wc;
3694         guint16 bc;
3695
3696         WORD_COUNT;
3697
3698         /* create time */
3699         offset = dissect_smb_datetime(tvb, tree, offset,
3700                 hf_smb_create_time,
3701                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3702
3703         /* access time */
3704         offset = dissect_smb_datetime(tvb, tree, offset,
3705                 hf_smb_access_time,
3706                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3707
3708         /* last write time */
3709         offset = dissect_smb_datetime(tvb, tree, offset,
3710                 hf_smb_last_write_time,
3711                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3712
3713         /* data size */
3714         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3715         offset += 4;
3716
3717         /* allocation size */
3718         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3719         offset += 4;
3720
3721         /* File Attributes */
3722         offset = dissect_file_attributes(tvb, tree, offset);
3723
3724         BYTE_COUNT;
3725
3726         END_OF_SMB
3727
3728         return offset;
3729 }
3730
3731 static int
3732 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3733 {
3734         guint8 wc;
3735         guint16 cnt=0;
3736         guint16 bc, fid;
3737
3738         WORD_COUNT;
3739
3740         /* fid */
3741         fid = tvb_get_letohs(tvb, offset);
3742         add_fid(tvb, pinfo, tree, offset, 2, fid);
3743         offset += 2;
3744
3745         /* write count */
3746         cnt = tvb_get_letohs(tvb, offset);
3747         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3748         offset += 2;
3749
3750         /* offset */
3751         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3752         offset += 4;
3753
3754         /* last write time */
3755         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3756         
3757         if(wc==12){
3758                 /* 12 reserved bytes */
3759                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3760                 offset += 12;
3761         }
3762
3763         BYTE_COUNT;
3764
3765         /* 1 pad byte */
3766         CHECK_BYTE_COUNT(1);
3767         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3768         COUNT_BYTES(1);
3769         
3770         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3771         bc = 0; /* XXX */
3772
3773         END_OF_SMB
3774
3775         return offset;
3776 }
3777  
3778 static int
3779 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3780 {
3781         guint8 wc;
3782         guint16 bc;
3783
3784         WORD_COUNT;
3785
3786         /* write count */
3787         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3788         offset += 2;
3789
3790         BYTE_COUNT;
3791
3792         END_OF_SMB
3793
3794         return offset;
3795 }
3796
3797 static int
3798 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3799 {
3800         guint8 wc;
3801         guint16 bc, fid;
3802         guint32 to;
3803
3804         WORD_COUNT;
3805
3806         /* fid */
3807         fid = tvb_get_letohs(tvb, offset);
3808         add_fid(tvb, pinfo, tree, offset, 2, fid);
3809         offset += 2;
3810
3811         /* offset */
3812         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3813         offset += 4;
3814
3815         /* max count */
3816         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3817         offset += 2;
3818
3819         /* min count */
3820         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3821         offset += 2;
3822
3823         /* timeout */
3824         to = tvb_get_letohl(tvb, offset);
3825         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3826         offset += 4;
3827
3828         /* 2 reserved bytes */
3829         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3830         offset += 2;
3831
3832         if(wc==10){
3833                 /* high offset */
3834                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3835                 offset += 4;
3836         }
3837
3838         BYTE_COUNT;
3839
3840         END_OF_SMB
3841
3842         return offset;
3843 }
3844
3845 static int
3846 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3847 {
3848         guint8 wc;
3849         guint16 bc;
3850
3851         WORD_COUNT;
3852
3853         /* units */
3854         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3855         offset += 2;
3856
3857         /* bpu */
3858         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3859         offset += 2;
3860
3861         /* block size */
3862         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3863         offset += 2;
3864
3865         /* free units */
3866         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3867         offset += 2;
3868
3869         /* 2 reserved bytes */
3870         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3871         offset += 2;
3872
3873         BYTE_COUNT;
3874
3875         END_OF_SMB
3876
3877         return offset;
3878 }
3879
3880 static int
3881 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3882 {
3883         guint8 wc;
3884         guint16 bc, fid;
3885
3886         WORD_COUNT;
3887
3888         /* fid */
3889         fid = tvb_get_letohs(tvb, offset);
3890         add_fid(tvb, pinfo, tree, offset, 2, fid);
3891         offset += 2;
3892
3893         /* offset */
3894         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3895         offset += 4;
3896
3897         /* max count */
3898         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3899         offset += 2;
3900
3901         /* min count */
3902         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3903         offset += 2;
3904
3905         /* 6 reserved bytes */
3906         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3907         offset += 6;
3908
3909         BYTE_COUNT;
3910
3911         END_OF_SMB
3912
3913         return offset;
3914 }
3915
3916 static int
3917 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3918 {
3919         guint16 datalen=0, bc;
3920         guint8 wc;
3921
3922         WORD_COUNT;
3923
3924         /* offset */
3925         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3926         offset += 4;
3927
3928         /* count */
3929         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3930         offset += 2;
3931
3932         /* 2 reserved bytes */
3933         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3934         offset += 2;
3935
3936         /* data compaction mode */
3937         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3938         offset += 2;
3939
3940         /* 2 reserved bytes */
3941         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3942         offset += 2;
3943
3944         /* data len */
3945         datalen = tvb_get_letohs(tvb, offset);
3946         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3947         offset += 2;
3948
3949         /* data offset */
3950         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3951         offset += 2;
3952
3953         BYTE_COUNT;
3954
3955         /* file data */
3956         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
3957         bc = 0;
3958
3959         END_OF_SMB
3960
3961         return offset;
3962 }
3963
3964
3965 static const true_false_string tfs_write_mode_write_through = {
3966         "WRITE THROUGH requested",
3967         "Write through not requested"
3968 };
3969 static const true_false_string tfs_write_mode_return_remaining = {
3970         "RETURN REMAINING (pipe/dev) requested",
3971         "DON'T return remaining (pipe/dev)"
3972 };
3973 static const true_false_string tfs_write_mode_raw = {
3974         "Use WriteRawNamedPipe (pipe)",
3975         "DON'T use WriteRawNamedPipe (pipe)"
3976 };
3977 static const true_false_string tfs_write_mode_message_start = {
3978         "This is the START of a MESSAGE (pipe)",
3979         "This is NOT the start of a message (pipe)"
3980 };
3981 static const true_false_string tfs_write_mode_connectionless = {
3982         "CONNECTIONLESS mode requested",
3983         "Connectionless mode NOT requested"
3984 };
3985 static int
3986 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
3987 {
3988         guint16 mask;
3989         proto_item *item = NULL;
3990         proto_tree *tree = NULL;
3991
3992         mask = tvb_get_letohs(tvb, offset);
3993
3994         if(parent_tree){
3995                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3996                         "Write Mode: 0x%04x", mask);
3997                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3998         }
3999
4000         if(bm&0x0080){
4001                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4002                         tvb, offset, 2, mask);
4003         }
4004         if(bm&0x0008){
4005                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4006                         tvb, offset, 2, mask);
4007         }
4008         if(bm&0x0004){
4009                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4010                         tvb, offset, 2, mask);
4011         }
4012         if(bm&0x0002){
4013                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4014                         tvb, offset, 2, mask);
4015         }
4016         if(bm&0x0001){
4017                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4018                         tvb, offset, 2, mask);
4019         }
4020
4021         offset += 2;
4022         return offset;
4023 }
4024
4025 static int
4026 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4027 {
4028         guint32 to;
4029         guint16 datalen=0, bc, fid;
4030         guint8 wc;
4031
4032         WORD_COUNT;
4033
4034         /* fid */
4035         fid = tvb_get_letohs(tvb, offset);
4036         add_fid(tvb, pinfo, tree, offset, 2, fid);
4037         offset += 2;
4038
4039         /* total data length */
4040         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4041         offset += 2;
4042
4043         /* 2 reserved bytes */
4044         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4045         offset += 2;
4046
4047         /* offset */
4048         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4049         offset += 4;
4050
4051         /* timeout */
4052         to = tvb_get_letohl(tvb, offset);
4053         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4054         offset += 4;
4055
4056         /* mode */
4057         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4058
4059         /* 4 reserved bytes */
4060         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4061         offset += 4;
4062
4063         /* data len */
4064         datalen = tvb_get_letohs(tvb, offset);
4065         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4066         offset += 2;
4067
4068         /* data offset */
4069         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4070         offset += 2;
4071