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