Reassembly of fragmented NT Transaction responses, from Ronnie Sahlberg.
[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.189 2001/12/18 08:55:49 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         guint16 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 /* matched smb_saved_info structures.
796   For matched smb_saved_info structures we store the smb_saved_info
797   structure twice in the table using the frame number and the MID as the key.
798   The frame number is guaranteed to be unique but if ever someone makes
799   some change that will renumber the frames in a capture we are in BIG trouble.
800   This is not likely though since that would break (among other things) all the
801   reassembly routines as well.
802
803   We also need the MID as there may be more than one SMB request or reply
804   in a single frame
805
806   Oh, yes, the key is really a pointer, but we use it as if it was an integer.
807   Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
808 */
809 static gint
810 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
811 {
812         register int key1 = (int)k1;
813         register int key2 = (int)k2;
814         return key1==key2;
815 }
816 static guint
817 smb_saved_info_hash_unmatched(gconstpointer k)
818 {
819         register int key = (int)k;
820         return key;
821 }
822
823 static gint
824 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
825 {
826         const smb_saved_info_key_t *key1 = k1;
827         const smb_saved_info_key_t *key2 = k2;
828         return key1->frame == key2->frame && key1->mid == key2->mid;
829 }
830 static guint
831 smb_saved_info_hash_matched(gconstpointer k)
832 {
833         const smb_saved_info_key_t *key = k;
834         return key->frame + key->mid;
835 }
836
837 /*
838  * The information we need to save about an NT Transaction request in order
839  * to dissect the reply.
840  */
841 typedef struct {
842         int subcmd;
843 } smb_nt_transact_info_t;
844
845 static GMemChunk *smb_nt_transact_info_chunk = NULL;
846 static int smb_nt_transact_info_init_count = 200;
847
848 /*
849  * The information we need to save about a Transaction2 request in order
850  * to dissect the reply.
851  */
852 typedef struct {
853         int subcmd;
854         int info_level;
855 } smb_transact2_info_t;
856
857 static GMemChunk *smb_transact2_info_chunk = NULL;
858 static int smb_transact2_info_init_count = 200;
859
860 /*
861  * The information we need to save about a Transaction request in order
862  * to dissect the reply; this includes information for use by the
863  * Remote API dissector.
864  */
865 static GMemChunk *smb_transact_info_chunk = NULL;
866 static int smb_transact_info_init_count = 200;
867
868 static GMemChunk *conv_tables_chunk = NULL;
869 static GSList *conv_tables = NULL;
870 static int conv_tables_count = 10;
871
872
873 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
874    End of request/response matching functions
875    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
876
877 static const value_string buffer_format_vals[] = {
878         {1,     "Data Block"},
879         {2,     "Dialect"},
880         {3,     "Pathname"},
881         {4,     "ASCII"},
882         {5,     "Variable Block"},
883         {0,     NULL}
884 };
885
886 /*
887  * UTIME - this is *almost* like a UNIX time stamp, except that it's
888  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
889  * January 1, 1970, 00:00:00 GMT.
890  *
891  * This means we have to do some extra work to convert it.  This code is
892  * based on the Samba code:
893  *
894  *      Unix SMB/Netbios implementation.
895  *      Version 1.9.
896  *      time handling functions
897  *      Copyright (C) Andrew Tridgell 1992-1998
898  */
899
900 /*
901  * Yield the difference between *A and *B, in seconds, ignoring leap
902  * seconds.
903  */
904 #define TM_YEAR_BASE 1900
905
906 static int
907 tm_diff(struct tm *a, struct tm *b)
908 {
909         int ay = a->tm_year + (TM_YEAR_BASE - 1);
910         int by = b->tm_year + (TM_YEAR_BASE - 1);
911         int intervening_leap_days =
912             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
913         int years = ay - by;
914         int days =
915             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
916         int hours = 24*days + (a->tm_hour - b->tm_hour);
917         int minutes = 60*hours + (a->tm_min - b->tm_min);
918         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
919
920         return seconds;
921 }
922
923 /*
924  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
925  * determined.
926  */
927 static int
928 TimeZone(time_t t)
929 {
930         struct tm *tm = gmtime(&t);
931         struct tm tm_utc;
932
933         if (tm == NULL)
934                 return 0;
935         tm_utc = *tm;
936         tm = localtime(&t);
937         if (tm == NULL)
938                 return 0;
939         return tm_diff(&tm_utc,tm);
940 }
941
942 /*
943  * Return the same value as TimeZone, but it should be more efficient.
944  *
945  * We keep a table of DST offsets to prevent calling localtime() on each 
946  * call of this function. This saves a LOT of time on many unixes.
947  *
948  * Updated by Paul Eggert <eggert@twinsun.com>
949  */
950 #ifndef CHAR_BIT
951 #define CHAR_BIT 8
952 #endif
953
954 #ifndef TIME_T_MIN
955 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
956                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
957 #endif
958 #ifndef TIME_T_MAX
959 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
960 #endif
961
962 static int
963 TimeZoneFaster(time_t t)
964 {
965         static struct dst_table {time_t start,end; int zone;} *tdt;
966         static struct dst_table *dst_table = NULL;
967         static int table_size = 0;
968         int i;
969         int zone = 0;
970
971         if (t == 0)
972                 t = time(NULL);
973
974         /* Tunis has a 8 day DST region, we need to be careful ... */
975 #define MAX_DST_WIDTH (365*24*60*60)
976 #define MAX_DST_SKIP (7*24*60*60)
977
978         for (i = 0; i < table_size; i++) {
979                 if (t >= dst_table[i].start && t <= dst_table[i].end)
980                         break;
981         }
982
983         if (i < table_size) {
984                 zone = dst_table[i].zone;
985         } else {
986                 time_t low,high;
987
988                 zone = TimeZone(t);
989                 if (dst_table == NULL)
990                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
991                 else
992                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
993                 if (tdt == NULL) {
994                         if (dst_table)
995                                 free(dst_table);
996                         table_size = 0;
997                 } else {
998                         dst_table = tdt;
999                         table_size++;
1000     
1001                         dst_table[i].zone = zone; 
1002                         dst_table[i].start = dst_table[i].end = t;
1003     
1004                         /* no entry will cover more than 6 months */
1005                         low = t - MAX_DST_WIDTH/2;
1006                         if (t < low)
1007                                 low = TIME_T_MIN;
1008       
1009                         high = t + MAX_DST_WIDTH/2;
1010                         if (high < t)
1011                                 high = TIME_T_MAX;
1012       
1013                         /*
1014                          * Widen the new entry using two bisection searches.
1015                          */
1016                         while (low+60*60 < dst_table[i].start) {
1017                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1018                                         t = dst_table[i].start - MAX_DST_SKIP;
1019                                 else
1020                                         t = low + (dst_table[i].start-low)/2;
1021                                 if (TimeZone(t) == zone)
1022                                         dst_table[i].start = t;
1023                                 else
1024                                         low = t;
1025                         }
1026
1027                         while (high-60*60 > dst_table[i].end) {
1028                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1029                                         t = dst_table[i].end + MAX_DST_SKIP;
1030                                 else
1031                                         t = high - (high-dst_table[i].end)/2;
1032                                 if (TimeZone(t) == zone)
1033                                         dst_table[i].end = t;
1034                                 else
1035                                         high = t;
1036                         }
1037                 }
1038         }
1039         return zone;
1040 }
1041
1042 /*
1043  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1044  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1045  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1046  * daylight savings transitions because some local times are ambiguous.
1047  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1048  */
1049 static int
1050 LocTimeDiff(time_t lt)
1051 {
1052         int d = TimeZoneFaster(lt);
1053         time_t t = lt + d;
1054
1055         /* if overflow occurred, ignore all the adjustments so far */
1056         if (((t < lt) ^ (d < 0)))
1057                 t = lt;
1058
1059         /*
1060          * Now t should be close enough to the true UTC to yield the
1061          * right answer.
1062          */
1063         return TimeZoneFaster(t);
1064 }
1065
1066 static int
1067 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1068 {
1069         guint32 timeval;
1070         nstime_t ts;
1071  
1072         timeval = tvb_get_letohl(tvb, offset);
1073         if (timeval == 0xffffffff) {
1074                 proto_tree_add_text(tree, tvb, offset, 4,
1075                     "%s: No time specified (0xffffffff)",
1076                     proto_registrar_get_name(hf_date));
1077                 offset += 4;
1078                 return offset;
1079         }
1080
1081         /*
1082          * We add the local time offset.
1083          */
1084         ts.secs = timeval + LocTimeDiff(timeval);
1085         ts.nsecs = 0;
1086
1087         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1088         offset += 4;
1089  
1090         return offset;
1091 }
1092
1093 static int
1094 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date)
1095 {
1096         proto_item *item = NULL;
1097         proto_tree *tree = NULL;
1098         nstime_t tv;
1099
1100         /* XXXX we need some way to represent this as a time
1101            properly. For now we display everything as 8 bytes*/
1102
1103         if(parent_tree){
1104                 item = proto_tree_add_text(parent_tree, tvb, offset, 8,
1105                         str);
1106                 tree = proto_item_add_subtree(item, ett_smb_64bit_time);
1107         }
1108
1109         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);
1110
1111         offset += 8;
1112         return offset;
1113 }
1114
1115 static int
1116 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
1117     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
1118     int hf_dos_time, gboolean time_first)
1119 {
1120         guint16 dos_time, dos_date;
1121         proto_item *item = NULL;
1122         proto_tree *tree = NULL;
1123         struct tm tm;
1124         time_t t;
1125         static const int mday_noleap[12] = {
1126                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1127         };
1128         static const int mday_leap[12] = {
1129                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1130         };
1131 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1132         nstime_t tv;
1133
1134         if (time_first) {
1135                 dos_time = tvb_get_letohs(tvb, offset);
1136                 dos_date = tvb_get_letohs(tvb, offset+2);
1137         } else {
1138                 dos_date = tvb_get_letohs(tvb, offset);
1139                 dos_time = tvb_get_letohs(tvb, offset+2);
1140         }
1141
1142         if ((dos_time == 0xffff && dos_time == 0xffff) ||
1143             (dos_time == 0 && dos_time == 0)) {
1144                 /*
1145                  * No date/time specified.
1146                  */
1147                 if(parent_tree){
1148                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1149                             "%s: No time specified (0x%08x)",
1150                             proto_registrar_get_name(hf_date),
1151                             (dos_date << 16) | dos_time);
1152                 }
1153                 offset += 4;
1154                 return offset;
1155         }
1156
1157         tm.tm_sec = (dos_time&0x1f)*2;
1158         tm.tm_min = (dos_time>>5)&0x3f;
1159         tm.tm_hour = (dos_time>>11)&0x1f;
1160         tm.tm_mday = dos_date&0x1f;
1161         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1162         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1163         tm.tm_isdst = -1;
1164
1165         /*
1166          * Do some sanity checks before calling "mktime()";
1167          * "mktime()" doesn't do them, it "normalizes" out-of-range
1168          * values.
1169          */
1170         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1171            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1172            (ISLEAP(tm.tm_year + 1900) ?
1173              tm.tm_mday > mday_leap[tm.tm_mon] :
1174              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1175              (t = mktime(&tm)) == -1) {
1176                 /*
1177                  * Invalid date/time.
1178                  */
1179                 if (parent_tree) {
1180                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1181                             "%s: Invalid time",
1182                             proto_registrar_get_name(hf_date));
1183                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1184                         if (time_first) {
1185                                 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);
1186                                 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);
1187                         } else {
1188                                 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);
1189                                 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);
1190                         }
1191                 }
1192                 offset += 4;
1193                 return offset;
1194         }
1195
1196         tv.secs = t;
1197         tv.nsecs = 0;
1198
1199         if(parent_tree){
1200                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1201                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1202                 if (time_first) {
1203                         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);
1204                         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);
1205                 } else {
1206                         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);
1207                         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);
1208                 }
1209         }
1210
1211         offset += 4;
1212
1213         return offset;
1214 }
1215
1216
1217 static const value_string da_access_vals[] = {
1218         { 0,            "Open for reading"},
1219         { 1,            "Open for writing"},
1220         { 2,            "Open for reading and writing"},
1221         { 3,            "Open for execute"},
1222         {0, NULL}
1223 };
1224 static const value_string da_sharing_vals[] = {
1225         { 0,            "Compatibility mode"},
1226         { 1,            "Deny read/write/execute (exclusive)"},
1227         { 2,            "Deny write"},
1228         { 3,            "Deny read/execute"},
1229         { 4,            "Deny none"},
1230         {0, NULL}
1231 };
1232 static const value_string da_locality_vals[] = {
1233         { 0,            "Locality of reference unknown"},
1234         { 1,            "Mainly sequential access"},
1235         { 2,            "Mainly random access"},
1236         { 3,            "Random access with some locality"},
1237         {0, NULL}
1238 };
1239 static const true_false_string tfs_da_caching = {
1240         "Do not cache this file",
1241         "Caching permitted on this file"
1242 };
1243 static const true_false_string tfs_da_writetru = {
1244         "Write through enabled",
1245         "Write through disabled"
1246 };
1247 static int
1248 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1249 {
1250         guint16 mask;
1251         proto_item *item = NULL;
1252         proto_tree *tree = NULL;
1253
1254         mask = tvb_get_letohs(tvb, offset);
1255
1256         if(parent_tree){
1257                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1258                         "%s Access: 0x%04x", type, mask);
1259                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1260         }
1261
1262         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1263                 tvb, offset, 2, mask);
1264         proto_tree_add_boolean(tree, hf_smb_access_caching,
1265                 tvb, offset, 2, mask);
1266         proto_tree_add_uint(tree, hf_smb_access_locality,
1267                 tvb, offset, 2, mask);
1268         proto_tree_add_uint(tree, hf_smb_access_sharing,
1269                 tvb, offset, 2, mask);
1270         proto_tree_add_uint(tree, hf_smb_access_mode,
1271                 tvb, offset, 2, mask);
1272
1273         offset += 2;
1274
1275         return offset;
1276 }
1277
1278 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1279 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1280 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1281 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1282 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1283 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1284 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1285 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1286 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1287 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1288 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1289 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1290 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1291 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1292 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1293
1294 /*
1295  * These are flags to be used in NT Create operations.
1296  */
1297 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1298 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1299 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1300 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1301 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1302 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1303 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1304
1305 static const true_false_string tfs_file_attribute_write_through = {
1306         "This object requires WRITE THROUGH",
1307         "This object does NOT require write through",
1308 };
1309 static const true_false_string tfs_file_attribute_no_buffering = {
1310         "This object requires NO BUFFERING",
1311         "This object can be buffered",
1312 };
1313 static const true_false_string tfs_file_attribute_random_access = {
1314         "This object will be RANDOM ACCESSed",
1315         "Random access is NOT requested",
1316 };
1317 static const true_false_string tfs_file_attribute_sequential_scan = {
1318         "This object is optimized for SEQUENTIAL SCAN",
1319         "This object is NOT optimized for sequential scan",
1320 };
1321 static const true_false_string tfs_file_attribute_delete_on_close = {
1322         "This object will be DELETED ON CLOSE",
1323         "This object will not be deleted on close",
1324 };
1325 static const true_false_string tfs_file_attribute_backup_semantics = {
1326         "This object supports BACKUP SEMANTICS",
1327         "This object does NOT support backup semantics",
1328 };
1329 static const true_false_string tfs_file_attribute_posix_semantics = {
1330         "This object supports POSIX SEMANTICS",
1331         "This object does NOT support POSIX semantics",
1332 };
1333 static const true_false_string tfs_file_attribute_read_only = {
1334         "This file is READ ONLY",
1335         "This file is NOT read only",
1336 };
1337 static const true_false_string tfs_file_attribute_hidden = {
1338         "This is a HIDDEN file",
1339         "This is NOT a hidden file"
1340 };
1341 static const true_false_string tfs_file_attribute_system = {
1342         "This is a SYSTEM file",
1343         "This is NOT a system file"
1344 };
1345 static const true_false_string tfs_file_attribute_volume = {
1346         "This is a VOLUME ID",
1347         "This is NOT a volume ID"
1348 };
1349 static const true_false_string tfs_file_attribute_directory = {
1350         "This is a DIRECTORY",
1351         "This is NOT a directory"
1352 };
1353 static const true_false_string tfs_file_attribute_archive = {
1354         "This is an ARCHIVE file",
1355         "This is NOT an archive file"
1356 };
1357 static const true_false_string tfs_file_attribute_device = {
1358         "This is a DEVICE",
1359         "This is NOT a device"
1360 };
1361 static const true_false_string tfs_file_attribute_normal = {
1362         "This file is an ordinary file",
1363         "This file has some attribute set"
1364 };
1365 static const true_false_string tfs_file_attribute_temporary = {
1366         "This is a TEMPORARY file",
1367         "This is NOT a temporary file"
1368 };
1369 static const true_false_string tfs_file_attribute_sparse = {
1370         "This is a SPARSE file",
1371         "This is NOT a sparse file"
1372 };
1373 static const true_false_string tfs_file_attribute_reparse = {
1374         "This file has an associated REPARSE POINT",
1375         "This file does NOT have an associated reparse point"
1376 };
1377 static const true_false_string tfs_file_attribute_compressed = {
1378         "This is a COMPRESSED file",
1379         "This is NOT a compressed file"
1380 };
1381 static const true_false_string tfs_file_attribute_offline = {
1382         "This file is OFFLINE",
1383         "This file is NOT offline"
1384 };
1385 static const true_false_string tfs_file_attribute_not_content_indexed = {
1386         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1387         "This file MAY be indexed by the content indexing service"
1388 };
1389 static const true_false_string tfs_file_attribute_encrypted = {
1390         "This is an ENCRYPTED file",
1391         "This is NOT an encrypted file"
1392 };
1393
1394 static int
1395 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1396 {
1397         guint16 mask;
1398         proto_item *item = NULL;
1399         proto_tree *tree = NULL;
1400
1401         mask = tvb_get_letohs(tvb, offset);
1402
1403         if(parent_tree){
1404                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1405                         "File Attributes: 0x%04x", mask);
1406                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1407         }
1408         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1409                 tvb, offset, 2, mask);
1410         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1411                 tvb, offset, 2, mask);
1412         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1413                 tvb, offset, 2, mask);
1414         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1415                 tvb, offset, 2, mask);
1416         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1417                 tvb, offset, 2, mask);
1418         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1419                 tvb, offset, 2, mask);
1420
1421         offset += 2;
1422
1423         return offset;
1424 }
1425
1426 /* 3.11 */
1427 static int
1428 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1429 {
1430         guint32 mask;
1431         proto_item *item = NULL;
1432         proto_tree *tree = NULL;
1433
1434         mask = tvb_get_letohl(tvb, offset);
1435
1436         if(parent_tree){
1437                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1438                         "File Attributes: 0x%08x", mask);
1439                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1440         }
1441
1442         /*
1443          * XXX - Network Monitor disagrees on some of the
1444          * bits, e.g. the bits above temporary are "atomic write"
1445          * and "transaction write", and it says nothing about the
1446          * bits above that.
1447          *
1448          * Does the Win32 API documentation, or the NT Native API book,
1449          * suggest anything?
1450          */
1451         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1452                 tvb, offset, 4, mask);
1453         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1454                 tvb, offset, 4, mask);
1455         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1456                 tvb, offset, 4, mask);
1457         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1458                 tvb, offset, 4, mask);
1459         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1460                 tvb, offset, 4, mask);
1461         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1462                 tvb, offset, 4, mask);
1463         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1464                 tvb, offset, 4, mask);
1465         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1466                 tvb, offset, 4, mask);
1467         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1468                 tvb, offset, 4, mask);
1469         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1470                 tvb, offset, 4, mask);
1471         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1472                 tvb, offset, 4, mask);
1473         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1474                 tvb, offset, 4, mask);
1475         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1476                 tvb, offset, 4, mask);
1477         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1478                 tvb, offset, 4, mask);
1479         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1480                 tvb, offset, 4, mask);
1481         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1482                 tvb, offset, 4, mask);
1483         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1484                 tvb, offset, 4, mask);
1485         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1486                 tvb, offset, 4, mask);
1487         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1488                 tvb, offset, 4, mask);
1489         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1490                 tvb, offset, 4, mask);
1491         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1492                 tvb, offset, 4, mask);
1493         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1494                 tvb, offset, 4, mask);
1495
1496         offset += 4;
1497
1498         return offset;
1499 }
1500
1501 static int
1502 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1503 {
1504         guint8 mask;
1505         proto_item *item = NULL;
1506         proto_tree *tree = NULL;
1507
1508         mask = tvb_get_guint8(tvb, offset);
1509
1510         if(parent_tree){
1511                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1512                         "File Attributes: 0x%02x", mask);
1513                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1514         }
1515         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1516                 tvb, offset, 1, mask);
1517         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1518                 tvb, offset, 1, mask);
1519         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1520                 tvb, offset, 1, mask);
1521         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1522                 tvb, offset, 1, mask);
1523         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1524                 tvb, offset, 1, mask);
1525         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1526                 tvb, offset, 1, mask);
1527
1528         offset += 1;
1529
1530         return offset;
1531 }
1532
1533 static const true_false_string tfs_search_attribute_read_only = {
1534         "Include READ ONLY files in search results",
1535         "Do NOT include read only files in search results",
1536 };
1537 static const true_false_string tfs_search_attribute_hidden = {
1538         "Include HIDDEN files in search results",
1539         "Do NOT include hidden files in search results"
1540 };
1541 static const true_false_string tfs_search_attribute_system = {
1542         "Include SYSTEM files in search results",
1543         "Do NOT include system files in search results"
1544 };
1545 static const true_false_string tfs_search_attribute_volume = {
1546         "Include VOLUME IDs in search results",
1547         "Do NOT include volume IDs in search results"
1548 };
1549 static const true_false_string tfs_search_attribute_directory = {
1550         "Include DIRECTORIES in search results",
1551         "Do NOT include directories in search results"
1552 };
1553 static const true_false_string tfs_search_attribute_archive = {
1554         "Include ARCHIVE files in search results",
1555         "Do NOT include archive files in search results"
1556 };
1557
1558 static int
1559 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1560 {
1561         guint16 mask;
1562         proto_item *item = NULL;
1563         proto_tree *tree = NULL;
1564
1565         mask = tvb_get_letohs(tvb, offset);
1566
1567         if(parent_tree){
1568                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1569                         "Search Attributes: 0x%04x", mask);
1570                 tree = proto_item_add_subtree(item, ett_smb_search);
1571         }
1572
1573         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1574                 tvb, offset, 2, mask);
1575         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1576                 tvb, offset, 2, mask);
1577         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1578                 tvb, offset, 2, mask);  
1579         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1580                 tvb, offset, 2, mask);
1581         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1582                 tvb, offset, 2, mask);
1583         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1584                 tvb, offset, 2, mask);
1585
1586         offset += 2;
1587         return offset;
1588 }
1589
1590 #if 0
1591 /*
1592  * XXX - this isn't used.
1593  * Is this used for anything?  NT Create AndX doesn't use it.
1594  * Is there some 16-bit attribute field with more bits than Read Only,
1595  * Hidden, System, Volume ID, Directory, and Archive?
1596  */
1597 static int
1598 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1599 {
1600         guint32 mask;
1601         proto_item *item = NULL;
1602         proto_tree *tree = NULL;
1603
1604         mask = tvb_get_letohl(tvb, offset);
1605
1606         if(parent_tree){
1607                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1608                         "File Attributes: 0x%08x", mask);
1609                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1610         }
1611         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1612                 tvb, offset, 2, mask);
1613         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1614                 tvb, offset, 2, mask);
1615         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1616                 tvb, offset, 2, mask);
1617         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1618                 tvb, offset, 2, mask);
1619         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1620                 tvb, offset, 2, mask);
1621         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1622                 tvb, offset, 2, mask);
1623         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1624                 tvb, offset, 2, mask);
1625         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1626                 tvb, offset, 2, mask);
1627         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1628                 tvb, offset, 2, mask);
1629         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1630                 tvb, offset, 2, mask);
1631         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1632                 tvb, offset, 2, mask);
1633         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1634                 tvb, offset, 2, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1636                 tvb, offset, 2, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1638                 tvb, offset, 2, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1640                 tvb, offset, 2, mask);
1641
1642         offset += 2;
1643
1644         return offset;
1645 }
1646 #endif
1647
1648
1649 #define SERVER_CAP_RAW_MODE            0x00000001
1650 #define SERVER_CAP_MPX_MODE            0x00000002
1651 #define SERVER_CAP_UNICODE             0x00000004
1652 #define SERVER_CAP_LARGE_FILES         0x00000008
1653 #define SERVER_CAP_NT_SMBS             0x00000010
1654 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1655 #define SERVER_CAP_STATUS32            0x00000040
1656 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1657 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1658 #define SERVER_CAP_NT_FIND             0x00000200
1659 #define SERVER_CAP_DFS                 0x00001000
1660 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1661 #define SERVER_CAP_LARGE_READX         0x00004000
1662 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1663 #define SERVER_CAP_UNIX                0x00800000
1664 #define SERVER_CAP_RESERVED            0x02000000
1665 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1666 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1667 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1668 static const true_false_string tfs_server_cap_raw_mode = {
1669         "Read Raw and Write Raw are supported",
1670         "Read Raw and Write Raw are not supported"
1671 };
1672 static const true_false_string tfs_server_cap_mpx_mode = {
1673         "Read Mpx and Write Mpx are supported",
1674         "Read Mpx and Write Mpx are not supported"
1675 };
1676 static const true_false_string tfs_server_cap_unicode = {
1677         "Unicode strings are supported",
1678         "Unicode strings are not supported"
1679 };
1680 static const true_false_string tfs_server_cap_large_files = {
1681         "Large files are supported",
1682         "Large files are not supported",
1683 };
1684 static const true_false_string tfs_server_cap_nt_smbs = {
1685         "NT SMBs are supported",
1686         "NT SMBs are not supported"
1687 };
1688 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1689         "RPC remote APIs are supported",
1690         "RPC remote APIs are not supported"
1691 };
1692 static const true_false_string tfs_server_cap_nt_status = {
1693         "NT status codes are supported",
1694         "NT status codes are not supported"
1695 };
1696 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1697         "Level 2 oplocks are supported",
1698         "Level 2 oplocks are not supported"
1699 };
1700 static const true_false_string tfs_server_cap_lock_and_read = {
1701         "Lock and Read is supported",
1702         "Lock and Read is not supported"
1703 };
1704 static const true_false_string tfs_server_cap_nt_find = {
1705         "NT Find is supported",
1706         "NT Find is not supported"
1707 };
1708 static const true_false_string tfs_server_cap_dfs = {
1709         "Dfs is supported",
1710         "Dfs is not supported"
1711 };
1712 static const true_false_string tfs_server_cap_infolevel_passthru = {
1713         "NT information level request passthrough is supported",
1714         "NT information level request passthrough is not supported"
1715 };
1716 static const true_false_string tfs_server_cap_large_readx = {
1717         "Large Read andX is supported",
1718         "Large Read andX is not supported"
1719 };
1720 static const true_false_string tfs_server_cap_large_writex = {
1721         "Large Write andX is supported",
1722         "Large Write andX is not supported"
1723 };
1724 static const true_false_string tfs_server_cap_unix = {
1725         "UNIX extensions are supported",
1726         "UNIX extensions are not supported"
1727 };
1728 static const true_false_string tfs_server_cap_reserved = {
1729         "Reserved",
1730         "Reserved"
1731 };
1732 static const true_false_string tfs_server_cap_bulk_transfer = {
1733         "Bulk Read and Bulk Write are supported",
1734         "Bulk Read and Bulk Write are not supported"
1735 };
1736 static const true_false_string tfs_server_cap_compressed_data = {
1737         "Compressed data transfer is supported",
1738         "Compressed data transfer is not supported"
1739 };
1740 static const true_false_string tfs_server_cap_extended_security = {
1741         "Extended security exchanges are supported",
1742         "Extended security exchanges are not supported"
1743 };
1744 static int
1745 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1746 {
1747         guint32 mask;
1748         proto_item *item = NULL;
1749         proto_tree *tree = NULL;
1750
1751         mask = tvb_get_letohl(tvb, offset);
1752
1753         if(parent_tree){
1754                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1755                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1756         }
1757
1758         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1759                 tvb, offset, 4, mask);
1760         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1761                 tvb, offset, 4, mask);
1762         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1763                 tvb, offset, 4, mask);
1764         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1765                 tvb, offset, 4, mask);
1766         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1767                 tvb, offset, 4, mask);
1768         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1769                 tvb, offset, 4, mask);
1770         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1771                 tvb, offset, 4, mask);
1772         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1773                 tvb, offset, 4, mask);
1774         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1775                 tvb, offset, 4, mask);
1776         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1777                 tvb, offset, 4, mask);
1778         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1779                 tvb, offset, 4, mask);
1780         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1781                 tvb, offset, 4, mask);
1782         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1783                 tvb, offset, 4, mask);
1784         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1785                 tvb, offset, 4, mask);
1786         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1787                 tvb, offset, 4, mask);
1788         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1789                 tvb, offset, 4, mask);
1790         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1791                 tvb, offset, 4, mask);
1792         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1793                 tvb, offset, 4, mask);
1794         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1795                 tvb, offset, 4, mask);
1796
1797         return mask;
1798 }
1799
1800 #define RAWMODE_READ   0x01
1801 #define RAWMODE_WRITE  0x02
1802 static const true_false_string tfs_rm_read = {
1803         "Read Raw is supported",
1804         "Read Raw is not supported"
1805 };
1806 static const true_false_string tfs_rm_write = {
1807         "Write Raw is supported",
1808         "Write Raw is not supported"
1809 };
1810
1811 static int
1812 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1813 {
1814         guint16 mask;
1815         proto_item *item = NULL;
1816         proto_tree *tree = NULL;
1817
1818         mask = tvb_get_letohs(tvb, offset);
1819
1820         if(parent_tree){
1821                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1822                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1823         }
1824
1825         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1826         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1827
1828         offset += 2;
1829
1830         return offset;
1831 }
1832
1833 #define SECURITY_MODE_MODE             0x01
1834 #define SECURITY_MODE_PASSWORD         0x02
1835 #define SECURITY_MODE_SIGNATURES       0x04
1836 #define SECURITY_MODE_SIG_REQUIRED     0x08
1837 static const true_false_string tfs_sm_mode = {
1838         "USER security mode",
1839         "SHARE security mode"
1840 };
1841 static const true_false_string tfs_sm_password = {
1842         "ENCRYPTED password. Use challenge/response",
1843         "PLAINTEXT password"
1844 };
1845 static const true_false_string tfs_sm_signatures = {
1846         "Security signatures ENABLED",
1847         "Security signatures NOT enabled"
1848 };
1849 static const true_false_string tfs_sm_sig_required = {
1850         "Security signatures REQUIRED",
1851         "Security signatures NOT required"
1852 };
1853
1854 static int
1855 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1856 {
1857         guint16 mask = 0;
1858         proto_item *item = NULL;
1859         proto_tree *tree = NULL;
1860
1861         switch(wc){
1862         case 13:
1863                 mask = tvb_get_letohs(tvb, offset);
1864                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1865                                 "Security Mode: 0x%04x", mask);
1866                 tree = proto_item_add_subtree(item, ett_smb_mode);
1867                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1868                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1869                 offset += 2;
1870                 break;
1871
1872         case 17:
1873                 mask = tvb_get_guint8(tvb, offset);
1874                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1875                                 "Security Mode: 0x%02x", mask);
1876                 tree = proto_item_add_subtree(item, ett_smb_mode);
1877                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1878                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1879                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1880                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1881                 offset += 1;
1882                 break;
1883         }
1884
1885         return offset;
1886 }
1887
1888 static int
1889 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1890 {
1891         proto_item *it = NULL;
1892         proto_tree *tr = NULL;
1893         guint16 bc;
1894         guint8 wc;
1895
1896         WORD_COUNT;
1897
1898         BYTE_COUNT;
1899
1900         if(tree){
1901                 it = proto_tree_add_text(tree, tvb, offset, bc,
1902                                 "Requested Dialects");
1903                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1904         }
1905
1906         while(bc){
1907                 int len;
1908                 const guint8 *str;
1909                 proto_item *dit = NULL;
1910                 proto_tree *dtr = NULL;
1911
1912                 /* XXX - what if this runs past bc? */
1913                 len = tvb_strsize(tvb, offset+1);
1914                 str = tvb_get_ptr(tvb, offset+1, len);
1915
1916                 if(tr){
1917                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
1918                                         "Dialect: %s", str);
1919                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
1920                 }
1921
1922                 /* Buffer Format */
1923                 CHECK_BYTE_COUNT(1);
1924                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
1925                         TRUE);
1926                 COUNT_BYTES(1);
1927
1928                 /*Dialect Name */
1929                 CHECK_BYTE_COUNT(len);
1930                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
1931                         len, str);
1932                 COUNT_BYTES(len);
1933         }
1934
1935         END_OF_SMB
1936
1937         return offset;
1938 }
1939
1940 static int
1941 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1942 {
1943         guint8 wc;
1944         guint16 dialect;
1945         const char *dn;
1946         int dn_len;
1947         guint16 bc;
1948         guint16 ekl=0;
1949         guint32 caps=0;
1950         gint16 tz;
1951
1952         WORD_COUNT;
1953
1954         /* Dialect Index */
1955         dialect = tvb_get_letohs(tvb, offset);
1956         switch(wc){
1957         case 1:
1958                 if(dialect==0xffff){
1959                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1960                                 tvb, offset, 2, dialect,
1961                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
1962                 } else {
1963                         proto_tree_add_uint(tree, hf_smb_dialect_index,
1964                                 tvb, offset, 2, dialect);
1965                 }
1966                 break;
1967         case 13:
1968                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1969                         tvb, offset, 2, dialect,
1970                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
1971                 break;
1972         case 17:
1973                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1974                         tvb, offset, 2, dialect,
1975                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
1976                 break;
1977         default:
1978                 proto_tree_add_text(tree, tvb, offset, wc*2,
1979                         "Words for unknown response format");
1980                 offset += wc*2;
1981                 goto bytecount;
1982         }
1983         offset += 2;
1984
1985         switch(wc){
1986         case 13:
1987                 /* Security Mode */
1988                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
1989                                 wc);
1990
1991                 /* Maximum Transmit Buffer Size */
1992                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
1993                         tvb, offset, 2, TRUE);
1994                 offset += 2;
1995
1996                 /* Maximum Multiplex Count */
1997                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
1998                         tvb, offset, 2, TRUE);
1999                 offset += 2;
2000
2001                 /* Maximum Vcs Number */
2002                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2003                         tvb, offset, 2, TRUE);
2004                 offset += 2;
2005
2006                 /* raw mode */
2007                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
2008
2009                 /* session key */
2010                 proto_tree_add_item(tree, hf_smb_session_key,
2011                         tvb, offset, 4, TRUE);
2012                 offset += 4;
2013
2014                 /* current time and date at server */
2015                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2016                     TRUE);
2017
2018                 /* time zone */
2019                 tz = tvb_get_letohs(tvb, offset);
2020                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2021                 offset += 2;
2022
2023                 /* encryption key length */
2024                 ekl = tvb_get_letohs(tvb, offset);
2025                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2026                 offset += 2;
2027
2028                 /* 2 reserved bytes */
2029                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2030                 offset += 2;
2031
2032                 break;
2033
2034         case 17:
2035                 /* Security Mode */
2036                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
2037
2038                 /* Maximum Multiplex Count */
2039                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2040                         tvb, offset, 2, TRUE);
2041                 offset += 2;
2042
2043                 /* Maximum Vcs Number */
2044                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2045                         tvb, offset, 2, TRUE);
2046                 offset += 2;
2047
2048                 /* Maximum Transmit Buffer Size */
2049                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2050                         tvb, offset, 4, TRUE);
2051                 offset += 4;
2052
2053                 /* maximum raw buffer size */
2054                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2055                         tvb, offset, 4, TRUE);
2056                 offset += 4;
2057
2058                 /* session key */
2059                 proto_tree_add_item(tree, hf_smb_session_key,
2060                         tvb, offset, 4, TRUE);
2061                 offset += 4;
2062
2063                 /* server capabilities */
2064                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
2065                 offset += 4;
2066
2067                 /* system time */
2068                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
2069                                 "System Time", hf_smb_system_time);
2070
2071                 /* time zone */
2072                 tz = tvb_get_letohs(tvb, offset);
2073                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2074                         tvb, offset, 2, tz,
2075                         "Server Time Zone: %d min from UTC", tz);
2076                 offset += 2;
2077
2078                 /* encryption key length */
2079                 ekl = tvb_get_guint8(tvb, offset);
2080                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2081                         tvb, offset, 1, ekl);
2082                 offset += 1;
2083
2084                 break;
2085         }
2086
2087         BYTE_COUNT;
2088
2089         switch(wc){
2090         case 13:
2091                 /* challenge/response encryption key */
2092                 if(ekl){
2093                         CHECK_BYTE_COUNT(ekl);
2094                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2095                         COUNT_BYTES(ekl);
2096                 }
2097
2098                 /* domain */
2099                 dn = get_unicode_or_ascii_string(tvb, &offset,
2100                         pinfo, &dn_len, FALSE, FALSE, &bc);
2101                 if (dn == NULL)
2102                         goto endofcommand;
2103                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2104                         offset, dn_len,dn);
2105                 COUNT_BYTES(dn_len);
2106                 break;
2107
2108         case 17:
2109                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2110                         smb_info_t *si;
2111
2112                         /* challenge/response encryption key */
2113                         /* XXX - is this aligned on an even boundary? */
2114                         if(ekl){
2115                                 CHECK_BYTE_COUNT(ekl);
2116                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2117                                         tvb, offset, ekl, TRUE);
2118                                 COUNT_BYTES(ekl);
2119                         }
2120
2121                         /* domain */
2122                         /* this string is special, unicode is flagged in caps */
2123                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2124                         si = pinfo->private_data;
2125                         si->unicode = (caps&SERVER_CAP_UNICODE);
2126                         dn = get_unicode_or_ascii_string(tvb,
2127                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2128                                 &bc);
2129                         if (dn == NULL)
2130                                 goto endofcommand;
2131                         proto_tree_add_string(tree, hf_smb_primary_domain,
2132                                 tvb, offset, dn_len, dn);
2133                         COUNT_BYTES(dn_len);
2134                 } else {
2135                         /* guid */
2136                         /* XXX - show it in the standard Microsoft format
2137                            for GUIDs? */
2138                         CHECK_BYTE_COUNT(16);
2139                         proto_tree_add_item(tree, hf_smb_server_guid,
2140                                 tvb, offset, 16, TRUE);
2141                         COUNT_BYTES(16);
2142
2143                         /* security blob */
2144                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2145                            data structure, at least in NT 5.0-and-later
2146                            server replies? */
2147                         if(bc){
2148                                 proto_tree_add_item(tree, hf_smb_security_blob,
2149                                         tvb, offset, bc, TRUE);
2150                                 COUNT_BYTES(bc);
2151                         }
2152                 }
2153                 break;
2154         }
2155
2156         END_OF_SMB
2157
2158         return offset;
2159 }
2160
2161
2162 static int
2163 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2164 {
2165         int dn_len;
2166         const char *dn;
2167         guint8 wc;
2168         guint16 bc;
2169
2170         WORD_COUNT;
2171  
2172         BYTE_COUNT;
2173
2174         /* buffer format */
2175         CHECK_BYTE_COUNT(1);
2176         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2177         COUNT_BYTES(1);
2178
2179         /* dir name */
2180         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2181                 FALSE, FALSE, &bc);
2182         if (dn == NULL)
2183                 goto endofcommand;
2184         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2185                 dn);
2186         COUNT_BYTES(dn_len);
2187
2188         if (check_col(pinfo->cinfo, COL_INFO)) {
2189                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2190         }
2191
2192         END_OF_SMB
2193
2194         return offset;
2195 }
2196
2197 static int
2198 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2199 {
2200         guint8 wc;
2201         guint16 bc;
2202  
2203         WORD_COUNT;
2204  
2205         BYTE_COUNT;
2206
2207         END_OF_SMB
2208
2209         return offset;
2210 }
2211
2212 static int
2213 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2214 {
2215         guint16 ec, bc;
2216         guint8 wc;
2217
2218         WORD_COUNT;
2219
2220         /* echo count */
2221         ec = tvb_get_letohs(tvb, offset);
2222         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2223         offset += 2;
2224
2225         BYTE_COUNT;
2226
2227         if (bc != 0) {
2228                 /* echo data */
2229                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2230                 COUNT_BYTES(bc);
2231         }
2232
2233         END_OF_SMB
2234
2235         return offset;
2236 }
2237
2238 static int
2239 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2240 {
2241         guint16 bc;
2242         guint8 wc;
2243
2244         WORD_COUNT;
2245
2246         /* echo sequence number */
2247         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2248         offset += 2;
2249
2250         BYTE_COUNT;
2251
2252         if (bc != 0) {
2253                 /* echo data */
2254                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2255                 COUNT_BYTES(bc);
2256         }
2257
2258         END_OF_SMB
2259
2260         return offset;
2261 }
2262
2263 static int
2264 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2265 {
2266         int an_len, pwlen;
2267         const char *an;
2268         guint8 wc;
2269         guint16 bc;
2270
2271         WORD_COUNT;
2272  
2273         BYTE_COUNT;
2274
2275         /* buffer format */
2276         CHECK_BYTE_COUNT(1);
2277         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2278         COUNT_BYTES(1);
2279
2280         /* Path */
2281         an = get_unicode_or_ascii_string(tvb, &offset,
2282                 pinfo, &an_len, FALSE, FALSE, &bc);
2283         if (an == NULL)
2284                 goto endofcommand;
2285         proto_tree_add_string(tree, hf_smb_path, tvb,
2286                 offset, an_len, an);
2287         COUNT_BYTES(an_len);
2288
2289         if (check_col(pinfo->cinfo, COL_INFO)) {
2290                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2291         }
2292
2293         /* buffer format */
2294         CHECK_BYTE_COUNT(1);
2295         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2296         COUNT_BYTES(1);
2297
2298         /* password, ANSI */
2299         /* XXX - what if this runs past bc? */
2300         pwlen = tvb_strsize(tvb, offset);
2301         CHECK_BYTE_COUNT(pwlen);
2302         proto_tree_add_item(tree, hf_smb_password,
2303                 tvb, offset, pwlen, TRUE);
2304         COUNT_BYTES(pwlen);
2305
2306         /* buffer format */
2307         CHECK_BYTE_COUNT(1);
2308         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2309         COUNT_BYTES(1);
2310
2311         /* Service */
2312         an = get_unicode_or_ascii_string(tvb, &offset,
2313                 pinfo, &an_len, FALSE, FALSE, &bc);
2314         if (an == NULL)
2315                 goto endofcommand;
2316         proto_tree_add_string(tree, hf_smb_service, tvb,
2317                 offset, an_len, an);
2318         COUNT_BYTES(an_len);
2319
2320         END_OF_SMB
2321
2322         return offset;
2323 }
2324
2325 static int
2326 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2327 {
2328         guint8 wc;
2329         guint16 bc;
2330
2331         WORD_COUNT;
2332  
2333         /* Maximum Buffer Size */
2334         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2335         offset += 2;
2336
2337         /* tid */
2338         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2339         offset += 2;
2340
2341         BYTE_COUNT;
2342
2343         END_OF_SMB
2344
2345         return offset;
2346 }
2347  
2348
2349 static const true_false_string tfs_of_create = {
2350         "Create file if it does not exist",
2351         "Fail if file does not exist"
2352 };
2353 static const value_string of_open[] = {
2354         { 0,            "Fail if file exists"},
2355         { 1,            "Open file if it exists"},
2356         { 2,            "Truncate file if it exists"},
2357         {0, NULL}
2358 };
2359 static int
2360 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2361 {
2362         guint16 mask;
2363         proto_item *item = NULL;
2364         proto_tree *tree = NULL;
2365
2366         mask = tvb_get_letohs(tvb, offset);
2367
2368         if(parent_tree){
2369                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2370                         "Open Function: 0x%04x", mask);
2371                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2372         }
2373
2374         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2375                 tvb, offset, 2, mask);
2376         proto_tree_add_uint(tree, hf_smb_open_function_open,
2377                 tvb, offset, 2, mask);
2378
2379         offset += 2;
2380
2381         return offset;
2382 }
2383
2384
2385 static const true_false_string tfs_mf_file = {
2386         "Target must be a file",
2387         "Target needn't be a file"
2388  };
2389 static const true_false_string tfs_mf_dir = {
2390         "Target must be a directory",
2391         "Target needn't be a directory"
2392 };
2393 static const true_false_string tfs_mf_verify = {
2394         "MUST verify all writes",
2395         "Don't have to verify writes"
2396 };
2397 static int
2398 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2399 {
2400         guint16 mask;
2401         proto_item *item = NULL;
2402         proto_tree *tree = NULL;
2403
2404         mask = tvb_get_letohs(tvb, offset);
2405
2406         if(parent_tree){
2407                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2408                         "Flags: 0x%04x", mask);
2409                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2410         }
2411  
2412         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2413                 tvb, offset, 2, mask);
2414         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2415                 tvb, offset, 2, mask);
2416         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2417                 tvb, offset, 2, mask);
2418
2419         offset += 2;
2420
2421         return offset;
2422 }
2423
2424 static int
2425 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2426 {
2427         int fn_len;
2428         guint16 tid;
2429         guint16 bc;
2430         guint8 wc;
2431         const char *fn;
2432
2433         WORD_COUNT;
2434
2435         /* tid */
2436         tid = tvb_get_letohs(tvb, offset);
2437         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2438                 "TID (target): 0x%04x", tid);
2439         offset += 2;
2440
2441         /* open function */
2442         offset = dissect_open_function(tvb, pinfo, tree, offset);
2443
2444         /* move flags */
2445         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2446
2447         BYTE_COUNT;
2448
2449         /* buffer format */
2450         CHECK_BYTE_COUNT(1);
2451         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2452         COUNT_BYTES(1);
2453
2454         /* file name */
2455         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2456                 FALSE, FALSE, &bc);
2457         if (fn == NULL)
2458                 goto endofcommand;
2459         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2460                 fn_len, fn, "Old File Name: %s", fn);
2461         COUNT_BYTES(fn_len);
2462
2463         if (check_col(pinfo->cinfo, COL_INFO)) {
2464                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2465         }
2466
2467         /* buffer format */
2468         CHECK_BYTE_COUNT(1);
2469         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2470         COUNT_BYTES(1);
2471
2472         /* file name */
2473         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2474                 FALSE, FALSE, &bc);
2475         if (fn == NULL)
2476                 goto endofcommand;
2477         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2478                 fn_len, fn, "New File Name: %s", fn);
2479         COUNT_BYTES(fn_len);
2480
2481         if (check_col(pinfo->cinfo, COL_INFO)) {
2482                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2483         }
2484
2485         END_OF_SMB
2486
2487         return offset;
2488 }
2489
2490 static int
2491 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2492 {
2493         int fn_len;
2494         const char *fn;
2495         guint8 wc;
2496         guint16 bc;
2497
2498         WORD_COUNT;
2499
2500         /* # of files moved */
2501         proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
2502         offset += 2;
2503
2504         BYTE_COUNT;
2505
2506         /* buffer format */
2507         CHECK_BYTE_COUNT(1);
2508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2509         COUNT_BYTES(1);
2510
2511         /* file name */
2512         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2513                 FALSE, FALSE, &bc);
2514         if (fn == NULL)
2515                 goto endofcommand;
2516         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2517                 fn);
2518         COUNT_BYTES(fn_len);
2519
2520         END_OF_SMB
2521
2522         return offset;
2523 }
2524
2525 static int
2526 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2527 {
2528         int fn_len;
2529         const char *fn;
2530         guint8 wc;
2531         guint16 bc;
2532
2533         WORD_COUNT;
2534
2535         /* desired access */
2536         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2537
2538         /* Search Attributes */
2539         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2540
2541         BYTE_COUNT;
2542
2543         /* buffer format */
2544         CHECK_BYTE_COUNT(1);
2545         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2546         COUNT_BYTES(1);
2547
2548         /* file name */
2549         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2550                 FALSE, FALSE, &bc);
2551         if (fn == NULL)
2552                 goto endofcommand;
2553         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2554                 fn);
2555         COUNT_BYTES(fn_len);
2556
2557         if (check_col(pinfo->cinfo, COL_INFO)) {
2558                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2559         }
2560
2561         END_OF_SMB
2562
2563         return offset;
2564 }
2565
2566 void
2567 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2568     int len, guint16 fid)
2569 {
2570         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2571         if (check_col(pinfo->cinfo, COL_INFO))
2572                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2573 }
2574
2575 static int
2576 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2577 {
2578         guint8 wc;
2579         guint16 bc;
2580         guint16 fid;
2581
2582         WORD_COUNT;
2583
2584         /* fid */
2585         fid = tvb_get_letohs(tvb, offset);
2586         add_fid(tvb, pinfo, tree, offset, 2, fid);
2587         offset += 2;
2588
2589         /* File Attributes */
2590         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2591
2592         /* last write time */
2593         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2594         
2595         /* File Size */
2596         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2597         offset += 4;
2598
2599         /* granted access */
2600         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2601
2602         BYTE_COUNT;
2603
2604         END_OF_SMB
2605
2606         return offset;
2607 }
2608
2609 static int
2610 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2611 {
2612         guint8 wc;
2613         guint16 bc;
2614         guint16 fid;
2615
2616         WORD_COUNT;
2617
2618         /* fid */
2619         fid = tvb_get_letohs(tvb, offset);
2620         add_fid(tvb, pinfo, tree, offset, 2, fid);
2621         offset += 2;
2622
2623         BYTE_COUNT;
2624
2625         END_OF_SMB
2626
2627         return offset;
2628 }
2629
2630 static int
2631 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2632 {
2633         int fn_len;
2634         const char *fn;
2635         guint8 wc;
2636         guint16 bc;
2637
2638         WORD_COUNT;
2639
2640         /* file attributes */
2641         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2642
2643         /* creation time */
2644         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2645
2646         BYTE_COUNT;
2647
2648         /* buffer format */
2649         CHECK_BYTE_COUNT(1);
2650         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2651         COUNT_BYTES(1);
2652
2653         /* File Name */
2654         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2655                 FALSE, FALSE, &bc);
2656         if (fn == NULL)
2657                 goto endofcommand;
2658         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2659                 fn);
2660         COUNT_BYTES(fn_len);
2661
2662         if (check_col(pinfo->cinfo, COL_INFO)) {
2663                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2664         }
2665
2666         END_OF_SMB
2667
2668         return offset;
2669 }
2670
2671 static int
2672 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2673 {
2674         guint8 wc;
2675         guint16 bc;
2676
2677         WORD_COUNT;
2678
2679         /* fid */
2680         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2681         offset += 2;
2682
2683         /* last write time */
2684         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2685
2686         BYTE_COUNT;
2687
2688         END_OF_SMB
2689
2690         return offset;
2691 }
2692
2693 static int
2694 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2695 {
2696         int fn_len;
2697         const char *fn;
2698         guint8 wc;
2699         guint16 bc;
2700
2701         WORD_COUNT;
2702
2703         /* search attributes */
2704         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2705
2706         BYTE_COUNT;
2707
2708         /* buffer format */
2709         CHECK_BYTE_COUNT(1);
2710         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2711         COUNT_BYTES(1);
2712
2713         /* file name */
2714         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2715                 FALSE, FALSE, &bc);
2716         if (fn == NULL)
2717                 goto endofcommand;
2718         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2719                 fn);
2720         COUNT_BYTES(fn_len);
2721
2722         if (check_col(pinfo->cinfo, COL_INFO)) {
2723                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2724         }
2725
2726         END_OF_SMB
2727
2728         return offset;
2729 }
2730
2731 static int
2732 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2733 {
2734         int fn_len;
2735         const char *fn;
2736         guint8 wc;
2737         guint16 bc;
2738
2739         WORD_COUNT;
2740
2741         /* search attributes */
2742         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2743
2744         BYTE_COUNT;
2745
2746         /* buffer format */
2747         CHECK_BYTE_COUNT(1);
2748         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2749         COUNT_BYTES(1);
2750
2751         /* old file name */
2752         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2753                 FALSE, FALSE, &bc);
2754         if (fn == NULL)
2755                 goto endofcommand;
2756         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2757                 fn);
2758         COUNT_BYTES(fn_len);
2759
2760         if (check_col(pinfo->cinfo, COL_INFO)) {
2761                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2762         }
2763
2764         /* buffer format */
2765         CHECK_BYTE_COUNT(1);
2766         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2767         COUNT_BYTES(1);
2768
2769         /* file name */
2770         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2771                 FALSE, FALSE, &bc);
2772         if (fn == NULL)
2773                 goto endofcommand;
2774         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2775                 fn);
2776         COUNT_BYTES(fn_len);
2777
2778         if (check_col(pinfo->cinfo, COL_INFO)) {
2779                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2780         }
2781
2782         END_OF_SMB
2783
2784         return offset;
2785 }
2786
2787 static int
2788 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2789 {
2790         guint16 bc;
2791         guint8 wc;
2792         const char *fn;
2793         int fn_len;
2794
2795         WORD_COUNT;
2796
2797         BYTE_COUNT;
2798
2799         /* Buffer Format */
2800         CHECK_BYTE_COUNT(1);
2801         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2802         COUNT_BYTES(1);
2803
2804         /* File Name */
2805         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2806                 FALSE, FALSE, &bc);
2807         if (fn == NULL)
2808                 goto endofcommand;
2809         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2810                 fn);
2811         COUNT_BYTES(fn_len);
2812
2813         if (check_col(pinfo->cinfo, COL_INFO)) {
2814                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2815         }
2816
2817         END_OF_SMB
2818
2819         return offset;
2820 }
2821  
2822 static int
2823 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2824 {
2825         guint16 bc;
2826         guint8 wc;
2827
2828         WORD_COUNT;
2829
2830         /* File Attributes */
2831         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2832
2833         /* Last Write Time */
2834         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2835
2836         /* File Size */
2837         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2838         offset += 4;
2839
2840         /* 10 reserved bytes */
2841         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2842         offset += 10;
2843
2844         BYTE_COUNT;
2845
2846         END_OF_SMB
2847
2848         return offset;
2849 }
2850
2851 static int
2852 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2853 {
2854         int fn_len;
2855         const char *fn;
2856         guint8 wc;
2857         guint16 bc;
2858
2859         WORD_COUNT;
2860
2861         /* file attributes */
2862         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2863
2864         /* last write time */
2865         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2866
2867         /* 10 reserved bytes */
2868         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2869         offset += 10;
2870
2871         BYTE_COUNT;
2872
2873         /* buffer format */
2874         CHECK_BYTE_COUNT(1);
2875         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2876         COUNT_BYTES(1);
2877
2878         /* file name */
2879         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2880                 FALSE, FALSE, &bc);
2881         if (fn == NULL)
2882                 goto endofcommand;
2883         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2884                 fn);
2885         COUNT_BYTES(fn_len);
2886
2887         if (check_col(pinfo->cinfo, COL_INFO)) {
2888                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2889         }
2890
2891         END_OF_SMB
2892
2893         return offset;
2894 }
2895
2896 static int
2897 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2898 {
2899         guint8 wc;
2900         guint16 bc;
2901
2902         WORD_COUNT;
2903
2904         /* fid */
2905         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2906         offset += 2;
2907
2908         /* read count */
2909         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
2910         offset += 2;
2911
2912         /* offset */
2913         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
2914         offset += 4;
2915
2916         /* remaining */
2917         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
2918         offset += 2;
2919
2920         BYTE_COUNT;
2921
2922         END_OF_SMB
2923
2924         return offset;
2925 }
2926
2927 int
2928 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
2929 {
2930         int tvblen;
2931
2932         if(bc>datalen){
2933                 /* We have some initial padding bytes. */
2934                 /* XXX - use the data offset here instead? */
2935                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
2936                         TRUE);
2937                 offset += bc-datalen;
2938                 bc = datalen;
2939         }
2940         tvblen = tvb_length_remaining(tvb, offset);
2941         if(bc>tvblen){
2942                 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);
2943                 offset += tvblen;
2944         } else {
2945                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
2946                 offset += bc;
2947         }
2948         return offset;
2949 }
2950
2951 static int
2952 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2953 {
2954         guint16 cnt=0, bc;
2955         guint8 wc;
2956
2957         WORD_COUNT;
2958
2959         /* read count */
2960         cnt = tvb_get_letohs(tvb, offset);
2961         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
2962         offset += 2;
2963
2964         /* 8 reserved bytes */
2965         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
2966         offset += 8;
2967
2968         BYTE_COUNT;
2969
2970         /* buffer format */
2971         CHECK_BYTE_COUNT(1);
2972         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2973         COUNT_BYTES(1);
2974
2975         /* data len */
2976         CHECK_BYTE_COUNT(2);
2977         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
2978         COUNT_BYTES(2);
2979
2980         if (bc != 0) {
2981                 /* file data */
2982                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
2983                 bc = 0;
2984         }
2985
2986         END_OF_SMB
2987
2988         return offset;
2989 }
2990
2991 static int
2992 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2993 {
2994         guint16 cnt, bc;
2995         guint8 wc;
2996
2997         WORD_COUNT;
2998
2999         /* read count */
3000         cnt = tvb_get_letohs(tvb, offset);
3001         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3002         offset += 2;
3003
3004         /* 8 reserved bytes */
3005         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3006         offset += 8;
3007
3008         BYTE_COUNT;
3009
3010         /* buffer format */
3011         CHECK_BYTE_COUNT(1);
3012         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3013         COUNT_BYTES(1);
3014
3015         /* data len */
3016         CHECK_BYTE_COUNT(2);
3017         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3018         COUNT_BYTES(2);
3019
3020         END_OF_SMB
3021
3022         return offset;
3023 }
3024
3025
3026 static int
3027 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3028 {
3029         guint16 cnt=0, bc;
3030         guint8 wc;
3031
3032         WORD_COUNT;
3033
3034         /* fid */
3035         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3036         offset += 2;
3037
3038         /* write count */
3039         cnt = tvb_get_letohs(tvb, offset);
3040         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3041         offset += 2;
3042
3043         /* offset */
3044         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3045         offset += 4;
3046
3047         /* remaining */
3048         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3049         offset += 2;
3050
3051         BYTE_COUNT;
3052
3053         /* buffer format */
3054         CHECK_BYTE_COUNT(1);
3055         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3056         COUNT_BYTES(1);
3057
3058         /* data len */
3059         CHECK_BYTE_COUNT(2);
3060         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3061         COUNT_BYTES(2);
3062
3063         if (bc != 0) {
3064                 /* file data */
3065                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3066                 bc = 0;
3067         }
3068
3069         END_OF_SMB
3070
3071         return offset;
3072 }
3073  
3074 static int
3075 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3076 {
3077         guint8 wc;
3078         guint16 bc;
3079
3080         WORD_COUNT;
3081
3082         /* write count */
3083         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3084         offset += 2;
3085
3086         BYTE_COUNT;
3087
3088         END_OF_SMB
3089
3090         return offset;
3091 }
3092
3093 static int
3094 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3095 {
3096         guint8 wc;
3097         guint16 bc;
3098
3099         WORD_COUNT;
3100
3101         /* fid */
3102         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3103         offset += 2;
3104
3105         /* lock count */
3106         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3107         offset += 4;
3108
3109         /* offset */
3110         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3111         offset += 4;
3112
3113         BYTE_COUNT;
3114
3115         END_OF_SMB
3116
3117         return offset;
3118 }
3119
3120 static int
3121 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3122 {
3123         int fn_len;
3124         const char *fn;
3125         guint8 wc;
3126         guint16 bc;
3127
3128         WORD_COUNT;
3129
3130         /* 2 reserved bytes */
3131         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3132         offset += 2;
3133
3134         /* Creation time */
3135         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3136
3137         BYTE_COUNT;
3138
3139         /* buffer format */
3140         CHECK_BYTE_COUNT(1);
3141         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3142         COUNT_BYTES(1);
3143
3144         /* directory name */
3145         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3146                 FALSE, FALSE, &bc);
3147         if (fn == NULL)
3148                 goto endofcommand;
3149         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3150                 fn);
3151         COUNT_BYTES(fn_len);
3152
3153         if (check_col(pinfo->cinfo, COL_INFO)) {
3154                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3155         }
3156
3157         END_OF_SMB
3158
3159         return offset;
3160 }
3161
3162 static int
3163 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3164 {
3165         int fn_len;
3166         const char *fn;
3167         guint8 wc;
3168         guint16 bc;
3169         guint16 fid;
3170
3171         WORD_COUNT;
3172
3173         /* fid */
3174         fid = tvb_get_letohs(tvb, offset);
3175         add_fid(tvb, pinfo, tree, offset, 2, fid);
3176         offset += 2;
3177
3178         BYTE_COUNT;
3179
3180         /* buffer format */
3181         CHECK_BYTE_COUNT(1);
3182         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3183         COUNT_BYTES(1);
3184
3185         /* file name */
3186         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3187                 FALSE, FALSE, &bc);
3188         if (fn == NULL)
3189                 goto endofcommand;
3190         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3191                 fn);
3192         COUNT_BYTES(fn_len);
3193
3194         END_OF_SMB
3195
3196         return offset;
3197 }
3198
3199 static const value_string seek_mode_vals[] = {
3200         {0,     "From Start Of File"},
3201         {1,     "From Current Position"},
3202         {2,     "From End Of File"},
3203         {0,     NULL}
3204 };
3205
3206 static int
3207 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3208 {
3209         guint8 wc;
3210         guint16 bc;
3211
3212         WORD_COUNT;
3213
3214         /* fid */
3215         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3216         offset += 2;
3217
3218         /* Seek Mode */
3219         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3220         offset += 2;
3221
3222         /* offset */
3223         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3224         offset += 4;
3225
3226         BYTE_COUNT;
3227
3228         END_OF_SMB
3229
3230         return offset;
3231 }
3232
3233 static int
3234 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3235 {
3236         guint8 wc;
3237         guint16 bc;
3238
3239         WORD_COUNT;
3240
3241         /* offset */
3242         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3243         offset += 4;
3244
3245         BYTE_COUNT;
3246
3247         END_OF_SMB
3248
3249         return offset;
3250 }
3251  
3252 static int
3253 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3254 {
3255         guint8 wc;
3256         guint16 bc;
3257
3258         WORD_COUNT;
3259
3260         /* fid */
3261         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3262         offset += 2;
3263
3264         /* create time */
3265         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3266                 hf_smb_create_time,
3267                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3268
3269         /* access time */
3270         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3271                 hf_smb_access_time,
3272                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3273
3274         /* last write time */
3275         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3276                 hf_smb_last_write_time,
3277                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3278
3279         BYTE_COUNT;
3280
3281         END_OF_SMB
3282
3283         return offset;
3284 }
3285
3286 static int
3287 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3288 {
3289         guint8 wc;
3290         guint16 bc;
3291
3292         WORD_COUNT;
3293
3294         /* create time */
3295         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3296                 hf_smb_create_time,
3297                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3298
3299         /* access time */
3300         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3301                 hf_smb_access_time,
3302                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3303
3304         /* last write time */
3305         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3306                 hf_smb_last_write_time,
3307                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3308
3309         /* data size */
3310         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3311         offset += 4;
3312
3313         /* allocation size */
3314         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3315         offset += 4;
3316
3317         /* File Attributes */
3318         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3319
3320         BYTE_COUNT;
3321
3322         END_OF_SMB
3323
3324         return offset;
3325 }
3326
3327 static int
3328 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3329 {
3330         guint8 wc;
3331         guint16 cnt=0;
3332         guint16 bc;
3333
3334         WORD_COUNT;
3335
3336         /* fid */
3337         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3338         offset += 2;
3339
3340         /* write count */
3341         cnt = tvb_get_letohs(tvb, offset);
3342         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3343         offset += 2;
3344
3345         /* offset */
3346         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3347         offset += 4;
3348
3349         /* last write time */
3350         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3351         
3352         if(wc==12){
3353                 /* 12 reserved bytes */
3354                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3355                 offset += 12;
3356         }
3357
3358         BYTE_COUNT;
3359
3360         /* 1 pad byte */
3361         CHECK_BYTE_COUNT(1);
3362         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3363         COUNT_BYTES(1);
3364         
3365         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3366         bc = 0; /* XXX */
3367
3368         END_OF_SMB
3369
3370         return offset;
3371 }
3372  
3373 static int
3374 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3375 {
3376         guint8 wc;
3377         guint16 bc;
3378
3379         WORD_COUNT;
3380
3381         /* write count */
3382         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3383         offset += 2;
3384
3385         BYTE_COUNT;
3386
3387         END_OF_SMB
3388
3389         return offset;
3390 }
3391
3392 static int
3393 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3394 {
3395         guint8 wc;
3396         guint16 bc;
3397         guint32 to;
3398
3399         WORD_COUNT;
3400
3401         /* fid */
3402         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3403         offset += 2;
3404
3405         /* offset */
3406         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3407         offset += 4;
3408
3409         /* max count */
3410         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3411         offset += 2;
3412
3413         /* min count */
3414         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3415         offset += 2;
3416
3417         /* timeout */
3418         to = tvb_get_letohl(tvb, offset);
3419         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3420         offset += 4;
3421
3422         /* 2 reserved bytes */
3423         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3424         offset += 2;
3425
3426         if(wc==10){
3427                 /* high offset */
3428                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3429                 offset += 4;
3430         }
3431
3432         BYTE_COUNT;
3433
3434         END_OF_SMB
3435
3436         return offset;
3437 }
3438
3439 static int
3440 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3441 {
3442         guint8 wc;
3443         guint16 bc;
3444
3445         WORD_COUNT;
3446
3447         /* units */
3448         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3449         offset += 2;
3450
3451         /* bpu */
3452         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3453         offset += 2;
3454
3455         /* block size */
3456         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3457         offset += 2;
3458
3459         /* free units */
3460         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3461         offset += 2;
3462
3463         /* 2 reserved bytes */
3464         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3465         offset += 2;
3466
3467         BYTE_COUNT;
3468
3469         END_OF_SMB
3470
3471         return offset;
3472 }
3473
3474 static int
3475 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3476 {
3477         guint8 wc;
3478         guint16 bc;
3479
3480         WORD_COUNT;
3481
3482         /* fid */
3483         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3484         offset += 2;
3485
3486         /* offset */
3487         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3488         offset += 4;
3489
3490         /* max count */
3491         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3492         offset += 2;
3493
3494         /* min count */
3495         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3496         offset += 2;
3497
3498         /* 6 reserved bytes */
3499         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3500         offset += 6;
3501
3502         BYTE_COUNT;
3503
3504         END_OF_SMB
3505
3506         return offset;
3507 }
3508
3509 static int
3510 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3511 {
3512         guint16 datalen=0, bc;
3513         guint8 wc;
3514
3515         WORD_COUNT;
3516
3517         /* offset */
3518         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3519         offset += 4;
3520
3521         /* count */
3522         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3523         offset += 2;
3524
3525         /* 2 reserved bytes */
3526         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3527         offset += 2;
3528
3529         /* data compaction mode */
3530         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3531         offset += 2;
3532
3533         /* 2 reserved bytes */
3534         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3535         offset += 2;
3536
3537         /* data len */
3538         datalen = tvb_get_letohs(tvb, offset);
3539         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3540         offset += 2;
3541
3542         /* data offset */
3543         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3544         offset += 2;
3545
3546         BYTE_COUNT;
3547
3548         /* file data */
3549         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3550         bc = 0;
3551
3552         END_OF_SMB
3553
3554         return offset;
3555 }
3556
3557
3558 static const true_false_string tfs_write_mode_write_through = {
3559         "WRITE THROUGH requested",
3560         "Write through not requested"
3561 };
3562 static const true_false_string tfs_write_mode_return_remaining = {
3563         "RETURN REMAINING (pipe/dev) requested",
3564         "DON'T return remaining (pipe/dev)"
3565 };
3566 static const true_false_string tfs_write_mode_raw = {
3567         "Use WriteRawNamedPipe (pipe)",
3568         "DON'T use WriteRawNamedPipe (pipe)"
3569 };
3570 static const true_false_string tfs_write_mode_message_start = {
3571         "This is the START of a MESSAGE (pipe)",
3572         "This is NOT the start of a message (pipe)"
3573 };
3574 static const true_false_string tfs_write_mode_connectionless = {
3575         "CONNECTIONLESS mode requested",
3576         "Connectionless mode NOT requested"
3577 };
3578 static int
3579 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3580 {
3581         guint16 mask;
3582         proto_item *item = NULL;
3583         proto_tree *tree = NULL;
3584
3585         mask = tvb_get_letohs(tvb, offset);
3586
3587         if(parent_tree){
3588                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3589                         "Write Mode: 0x%04x", mask);
3590                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3591         }
3592
3593         if(bm&0x0080){
3594                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3595                         tvb, offset, 2, mask);
3596         }
3597         if(bm&0x0008){
3598                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3599                         tvb, offset, 2, mask);
3600         }
3601         if(bm&0x0004){
3602                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3603                         tvb, offset, 2, mask);
3604         }
3605         if(bm&0x0002){
3606                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3607                         tvb, offset, 2, mask);
3608         }
3609         if(bm&0x0001){
3610                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3611                         tvb, offset, 2, mask);
3612         }
3613
3614         offset += 2;
3615         return offset;
3616 }
3617
3618 static int
3619 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3620 {
3621         guint32 to;
3622         guint16 datalen=0, bc;
3623         guint8 wc;
3624
3625         WORD_COUNT;
3626
3627         /* fid */
3628         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3629         offset += 2;
3630
3631         /* total data length */
3632         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3633         offset += 2;
3634
3635         /* 2 reserved bytes */
3636         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3637         offset += 2;
3638
3639         /* offset */
3640         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3641         offset += 4;
3642
3643         /* timeout */
3644         to = tvb_get_letohl(tvb, offset);
3645         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3646         offset += 4;
3647
3648         /* mode */
3649         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3650
3651         /* 4 reserved bytes */
3652         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3653         offset += 4;
3654
3655         /* data len */
3656         datalen = tvb_get_letohs(tvb, offset);
3657         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3658         offset += 2;
3659
3660         /* data offset */
3661         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3662         offset += 2;
3663
3664         BYTE_COUNT;
3665
3666         /* file data */
3667         /* XXX - use the data offset to determine where the data starts? */
3668         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3669         bc = 0;
3670
3671         END_OF_SMB
3672
3673         return offset;
3674 }
3675  
3676 static int
3677 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3678 {
3679         guint8 wc;
3680         guint16 bc;
3681
3682         WORD_COUNT;
3683
3684         /* remaining */
3685         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3686         offset += 2;
3687
3688         BYTE_COUNT;
3689
3690         END_OF_SMB
3691
3692         return offset;
3693 }
3694
3695 static int
3696 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3697 {
3698         guint32 to;
3699         guint16 datalen=0, bc;
3700         guint8 wc;
3701
3702         WORD_COUNT;
3703
3704         /* fid */
3705         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3706         offset += 2;
3707
3708         /* total data length */
3709         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3710         offset += 2;
3711
3712         /* 2 reserved bytes */
3713         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3714         offset += 2;
3715
3716         /* offset */
3717         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3718         offset += 4;
3719
3720         /* timeout */
3721         to = tvb_get_letohl(tvb, offset);
3722         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3723         offset += 4;
3724
3725         /* mode */
3726         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3727
3728         /* request mask */
3729         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3730         offset += 4;
3731         
3732         /* data len */
3733         datalen = tvb_get_letohs(tvb, offset);
3734         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3735         offset += 2;
3736
3737         /* data offset */
3738         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3739         offset += 2;
3740
3741         BYTE_COUNT;
3742
3743         /* file data */
3744         /* XXX - use the data offset to determine where the data starts? */
3745         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3746         bc = 0;
3747
3748         END_OF_SMB
3749
3750         return offset;
3751 }
3752  
3753 static int
3754 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3755 {
3756         guint8 wc;
3757         guint16 bc;
3758
3759         WORD_COUNT;
3760
3761         /* response mask */
3762         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
3763         offset += 4;
3764         
3765         BYTE_COUNT;
3766
3767         END_OF_SMB
3768
3769         return offset;
3770 }
3771
3772 static int
3773 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3774 {
3775         guint8 wc;
3776         guint16 bc;
3777
3778         WORD_COUNT;
3779
3780         /* sid */
3781         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
3782         offset += 2;
3783
3784         BYTE_COUNT;
3785
3786         END_OF_SMB
3787
3788         return offset;
3789 }
3790
3791 static int
3792 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
3793     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3794 {
3795         proto_item *item = NULL;
3796         proto_tree *tree = NULL;
3797         int fn_len;
3798         const char *fn;
3799         char fname[11+1];
3800
3801         if(parent_tree){
3802                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
3803                         "Resume Key");
3804                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
3805         }
3806
3807         /* reserved byte */
3808         CHECK_BYTE_COUNT_SUBR(1);
3809         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
3810         COUNT_BYTES_SUBR(1);
3811
3812         /* file name */
3813         fn_len = 11;
3814         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3815                 TRUE, TRUE, bcp);
3816         CHECK_STRING_SUBR(fn);
3817         /* ensure that it's null-terminated */
3818         strncpy(fname, fn, 11);
3819         fname[11] = '\0';
3820         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
3821                 fname);
3822         COUNT_BYTES_SUBR(fn_len);
3823
3824         /* server cookie */
3825         CHECK_BYTE_COUNT_SUBR(5);
3826         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
3827         COUNT_BYTES_SUBR(5);
3828
3829         /* client cookie */
3830         CHECK_BYTE_COUNT_SUBR(4);
3831         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
3832         COUNT_BYTES_SUBR(4);
3833
3834         *trunc = FALSE;
3835         return offset;
3836 }
3837
3838 static int
3839 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
3840     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3841 {
3842         proto_item *item = NULL;
3843         proto_tree *tree = NULL;
3844         int fn_len;
3845         const char *fn;
3846         char fname[13+1];
3847
3848         if(parent_tree){
3849                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
3850                         "Directory Information");
3851                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
3852         }
3853
3854         /* resume key */
3855         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
3856         if (*trunc)
3857                 return offset;
3858
3859         /* File Attributes */
3860         CHECK_BYTE_COUNT_SUBR(1);
3861         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
3862         *bcp -= 1;
3863
3864         /* last write time */
3865         CHECK_BYTE_COUNT_SUBR(4);
3866         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3867                 hf_smb_last_write_time,
3868                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
3869                 TRUE);
3870         *bcp -= 4;
3871
3872         /* File Size */
3873         CHECK_BYTE_COUNT_SUBR(4);
3874         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3875         COUNT_BYTES_SUBR(4);
3876
3877         /* file name */
3878         fn_len = 13;
3879         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3880                 TRUE, TRUE, bcp);
3881         CHECK_STRING_SUBR(fn);
3882         /* ensure that it's null-terminated */
3883         strncpy(fname, fn, 13);
3884         fname[13] = '\0';
3885         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3886                 fname);
3887         COUNT_BYTES_SUBR(fn_len);
3888
3889         *trunc = FALSE;
3890         return offset;
3891 }
3892
3893
3894 static int
3895 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3896 {
3897         int fn_len;
3898         const char *fn;
3899         guint16 rkl;
3900         guint8 wc;
3901         guint16 bc;
3902         gboolean trunc;
3903
3904         WORD_COUNT;
3905
3906         /* max count */
3907         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3908         offset += 2;
3909
3910         /* Search Attributes */
3911         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
3912
3913         BYTE_COUNT;
3914
3915         /* buffer format */
3916         CHECK_BYTE_COUNT(1);
3917         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3918         COUNT_BYTES(1);
3919
3920         /* file name */
3921         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3922                 TRUE, FALSE, &bc);
3923         if (fn == NULL)
3924                 goto endofcommand;
3925         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3926                 fn);
3927         COUNT_BYTES(fn_len);
3928
3929         if (check_col(pinfo->cinfo, COL_INFO)) {
3930                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
3931         }
3932
3933         /* buffer format */
3934         CHECK_BYTE_COUNT(1);
3935         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3936         COUNT_BYTES(1);
3937
3938         /* resume key length */
3939         CHECK_BYTE_COUNT(2);
3940         rkl = tvb_get_letohs(tvb, offset);
3941         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
3942         COUNT_BYTES(2);
3943
3944         /* resume key */
3945         if(rkl){
3946                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
3947                     &bc, &trunc);
3948                 if (trunc)
3949                         goto endofcommand;
3950         }
3951
3952         END_OF_SMB
3953
3954         return offset;
3955 }
3956
3957 static int
3958 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3959 {
3960         guint16 count=0;
3961         guint8 wc;
3962         guint16 bc;
3963         gboolean trunc;
3964
3965         WORD_COUNT;
3966
3967         /* count */
3968         count = tvb_get_letohs(tvb, offset);
3969         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
3970         offset += 2;
3971
3972         BYTE_COUNT;
3973
3974         /* buffer format */
3975         CHECK_BYTE_COUNT(1);
3976         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3977         COUNT_BYTES(1);
3978
3979         /* data len */
3980         CHECK_BYTE_COUNT(2);
3981         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3982         COUNT_BYTES(2);
3983
3984         while(count--){
3985                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
3986                     &bc, &trunc);
3987                 if (trunc)
3988                         goto endofcommand;
3989         }
3990
3991         END_OF_SMB
3992
3993         return offset;
3994 }
3995
3996 static const value_string locking_ol_vals[] = {
3997         {0,     "Client is not holding oplock on this file"},
3998         {1,     "Level 2 oplock currently held by client"},
3999         {0, NULL}
4000 };
4001
4002 static const true_false_string tfs_lock_type_large = {
4003         "Large file locking format requested",
4004         "Large file locking format not requested"
4005 };
4006 static const true_false_string tfs_lock_type_cancel = {
4007         "Cancel outstanding lock request",
4008         "Don't cancel outstanding lock request"
4009 };
4010 static const true_false_string tfs_lock_type_change = {
4011         "Change lock type",
4012         "Don't change lock type"
4013 };
4014 static const true_false_string tfs_lock_type_oplock = {
4015         "This is an oplock break notification/response",
4016         "This is not an oplock break notification/response"
4017 };
4018 static const true_false_string tfs_lock_type_shared = {
4019         "This is a shared lock",
4020         "This is an exclusive lock"
4021 };
4022 static int
4023 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4024 {
4025         guint8  wc, cmd=0xff, lt=0;
4026         guint16 andxoffset=0, un=0, ln=0, bc;
4027         guint32 to;
4028         proto_item *litem = NULL;
4029         proto_tree *ltree = NULL;
4030         proto_item *it = NULL;
4031         proto_tree *tr = NULL;
4032         int old_offset = offset;
4033
4034         WORD_COUNT;
4035
4036         /* next smb command */
4037         cmd = tvb_get_guint8(tvb, offset);
4038         if(cmd!=0xff){
4039                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4040         } else {
4041                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4042         }
4043         offset += 1;
4044
4045         /* reserved byte */
4046         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4047         offset += 1;
4048
4049         /* andxoffset */
4050         andxoffset = tvb_get_letohs(tvb, offset);
4051         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4052         offset += 2;
4053
4054         /* fid */
4055         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
4056         offset += 2;
4057
4058         /* lock type */
4059         lt = tvb_get_guint8(tvb, offset);
4060         if(tree){
4061                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4062                         "Lock Type: 0x%02x", lt);
4063                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4064         }
4065         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4066                 tvb, offset, 1, lt);
4067         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4068                 tvb, offset, 1, lt);
4069         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4070                 tvb, offset, 1, lt);
4071         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4072                 tvb, offset, 1, lt);
4073         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4074                 tvb, offset, 1, lt);
4075         offset += 1;
4076
4077         /* oplock level */
4078         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4079         offset += 1;
4080
4081         /* timeout */
4082         to = tvb_get_letohl(tvb, offset);
4083         if (to == 0)
4084                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4085         else if (to == 0xffffffff)
4086                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4087         else
4088                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4089         offset += 4;
4090
4091         /* number of unlocks */
4092         un = tvb_get_letohs(tvb, offset);
4093         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4094         offset += 2;
4095
4096         /* number of locks */
4097         ln = tvb_get_letohs(tvb, offset);
4098         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4099         offset += 2;
4100
4101         BYTE_COUNT;
4102
4103         /* unlocks */
4104         if(un){