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