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