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