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