From Laurent Rabret: use "g_free()", not "free()", to free stuff
[metze/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.344 2003/05/28 22:40:19 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #include <time.h>
36 #include <string.h>
37 #include <glib.h>
38 #include <ctype.h>
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include "smb.h"
42 #include "alignment.h"
43 #include <epan/strutil.h>
44 #include "prefs.h"
45 #include "reassemble.h"
46 #include "tap.h"
47 #include "packet-ipx.h"
48
49 #include "packet-smb-common.h"
50 #include "packet-smb-mailslot.h"
51 #include "packet-smb-pipe.h"
52 #include "packet-dcerpc.h"
53 #include "packet-smb-sidsnooping.h"
54
55 /*
56  * Various specifications and documents about SMB can be found in
57  *
58  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
59  *
60  * and a CIFS specification from the Storage Networking Industry Association
61  * can be found on a link from the page at
62  *
63  *      http://www.snia.org/tech_activities/CIFS
64  *
65  * (it supercedes the document at
66  *
67  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
68  *
69  * ).
70  *
71  * There are also some Open Group publications documenting CIFS available
72  * for download; catalog entries for them are at:
73  *
74  *      http://www.opengroup.org/products/publications/catalog/c209.htm
75  *
76  *      http://www.opengroup.org/products/publications/catalog/c195.htm
77  *
78  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
79  * can be found at
80  *
81  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
82  *
83  * (or, presumably a similar path under the Samba mirrors).  As the
84  * ".doc" indicates, it's a Word document.  Some of the specs from the
85  * Microsoft FTP site can be found in the
86  *
87  *      http://www.samba.org/samba/ftp/specs/
88  *
89  * directory as well.
90  *
91  * Beware - these specs may have errors.
92  */
93 static int proto_smb = -1;
94 static int hf_smb_cmd = -1;
95 static int hf_smb_key = -1;
96 static int hf_smb_session_id = -1;
97 static int hf_smb_sequence_num = -1;
98 static int hf_smb_group_id = -1;
99 static int hf_smb_pid = -1;
100 static int hf_smb_tid = -1;
101 static int hf_smb_uid = -1;
102 static int hf_smb_mid = -1;
103 static int hf_smb_response_to = -1;
104 static int hf_smb_time = -1;
105 static int hf_smb_response_in = -1;
106 static int hf_smb_continuation_to = -1;
107 static int hf_smb_nt_status = -1;
108 static int hf_smb_error_class = -1;
109 static int hf_smb_error_code = -1;
110 static int hf_smb_reserved = -1;
111 static int hf_smb_flags_lock = -1;
112 static int hf_smb_flags_receive_buffer = -1;
113 static int hf_smb_flags_caseless = -1;
114 static int hf_smb_flags_canon = -1;
115 static int hf_smb_flags_oplock = -1;
116 static int hf_smb_flags_notify = -1;
117 static int hf_smb_flags_response = -1;
118 static int hf_smb_flags2_long_names_allowed = -1;
119 static int hf_smb_flags2_ea = -1;
120 static int hf_smb_flags2_sec_sig = -1;
121 static int hf_smb_flags2_long_names_used = -1;
122 static int hf_smb_flags2_esn = -1;
123 static int hf_smb_flags2_dfs = -1;
124 static int hf_smb_flags2_roe = -1;
125 static int hf_smb_flags2_nt_error = -1;
126 static int hf_smb_flags2_string = -1;
127 static int hf_smb_word_count = -1;
128 static int hf_smb_byte_count = -1;
129 static int hf_smb_buffer_format = -1;
130 static int hf_smb_dialect_name = -1;
131 static int hf_smb_dialect_index = -1;
132 static int hf_smb_max_trans_buf_size = -1;
133 static int hf_smb_max_mpx_count = -1;
134 static int hf_smb_max_vcs_num = -1;
135 static int hf_smb_session_key = -1;
136 static int hf_smb_server_timezone = -1;
137 static int hf_smb_encryption_key_length = -1;
138 static int hf_smb_encryption_key = -1;
139 static int hf_smb_primary_domain = -1;
140 static int hf_smb_server = -1;
141 static int hf_smb_max_raw_buf_size = -1;
142 static int hf_smb_server_guid = -1;
143 static int hf_smb_security_blob_len = -1;
144 static int hf_smb_security_blob = -1;
145 static int hf_smb_sm_mode16 = -1;
146 static int hf_smb_sm_password16 = -1;
147 static int hf_smb_sm_mode = -1;
148 static int hf_smb_sm_password = -1;
149 static int hf_smb_sm_signatures = -1;
150 static int hf_smb_sm_sig_required = -1;
151 static int hf_smb_rm_read = -1;
152 static int hf_smb_rm_write = -1;
153 static int hf_smb_server_date_time = -1;
154 static int hf_smb_server_smb_date = -1;
155 static int hf_smb_server_smb_time = -1;
156 static int hf_smb_server_cap_raw_mode = -1;
157 static int hf_smb_server_cap_mpx_mode = -1;
158 static int hf_smb_server_cap_unicode = -1;
159 static int hf_smb_server_cap_large_files = -1;
160 static int hf_smb_server_cap_nt_smbs = -1;
161 static int hf_smb_server_cap_rpc_remote_apis = -1;
162 static int hf_smb_server_cap_nt_status = -1;
163 static int hf_smb_server_cap_level_ii_oplocks = -1;
164 static int hf_smb_server_cap_lock_and_read = -1;
165 static int hf_smb_server_cap_nt_find = -1;
166 static int hf_smb_server_cap_dfs = -1;
167 static int hf_smb_server_cap_infolevel_passthru = -1;
168 static int hf_smb_server_cap_large_readx = -1;
169 static int hf_smb_server_cap_large_writex = -1;
170 static int hf_smb_server_cap_unix = -1;
171 static int hf_smb_server_cap_reserved = -1;
172 static int hf_smb_server_cap_bulk_transfer = -1;
173 static int hf_smb_server_cap_compressed_data = -1;
174 static int hf_smb_server_cap_extended_security = -1;
175 static int hf_smb_system_time = -1;
176 static int hf_smb_unknown = -1;
177 static int hf_smb_dir_name = -1;
178 static int hf_smb_echo_count = -1;
179 static int hf_smb_echo_data = -1;
180 static int hf_smb_echo_seq_num = -1;
181 static int hf_smb_max_buf_size = -1;
182 static int hf_smb_password = -1;
183 static int hf_smb_password_len = -1;
184 static int hf_smb_ansi_password = -1;
185 static int hf_smb_ansi_password_len = -1;
186 static int hf_smb_unicode_password = -1;
187 static int hf_smb_unicode_password_len = -1;
188 static int hf_smb_path = -1;
189 static int hf_smb_service = -1;
190 static int hf_smb_move_flags_file = -1;
191 static int hf_smb_move_flags_dir = -1;
192 static int hf_smb_move_flags_verify = -1;
193 static int hf_smb_files_moved = -1;
194 static int hf_smb_copy_flags_file = -1;
195 static int hf_smb_copy_flags_dir = -1;
196 static int hf_smb_copy_flags_dest_mode = -1;
197 static int hf_smb_copy_flags_source_mode = -1;
198 static int hf_smb_copy_flags_verify = -1;
199 static int hf_smb_copy_flags_tree_copy = -1;
200 static int hf_smb_copy_flags_ea_action = -1;
201 static int hf_smb_count = -1;
202 static int hf_smb_file_name = -1;
203 static int hf_smb_open_function_open = -1;
204 static int hf_smb_open_function_create = -1;
205 static int hf_smb_fid = -1;
206 static int hf_smb_file_attr_read_only_16bit = -1;
207 static int hf_smb_file_attr_read_only_8bit = -1;
208 static int hf_smb_file_attr_hidden_16bit = -1;
209 static int hf_smb_file_attr_hidden_8bit = -1;
210 static int hf_smb_file_attr_system_16bit = -1;
211 static int hf_smb_file_attr_system_8bit = -1;
212 static int hf_smb_file_attr_volume_16bit = -1;
213 static int hf_smb_file_attr_volume_8bit = -1;
214 static int hf_smb_file_attr_directory_16bit = -1;
215 static int hf_smb_file_attr_directory_8bit = -1;
216 static int hf_smb_file_attr_archive_16bit = -1;
217 static int hf_smb_file_attr_archive_8bit = -1;
218 static int hf_smb_file_attr_device = -1;
219 static int hf_smb_file_attr_normal = -1;
220 static int hf_smb_file_attr_temporary = -1;
221 static int hf_smb_file_attr_sparse = -1;
222 static int hf_smb_file_attr_reparse = -1;
223 static int hf_smb_file_attr_compressed = -1;
224 static int hf_smb_file_attr_offline = -1;
225 static int hf_smb_file_attr_not_content_indexed = -1;
226 static int hf_smb_file_attr_encrypted = -1;
227 static int hf_smb_file_size = -1;
228 static int hf_smb_search_attribute_read_only = -1;
229 static int hf_smb_search_attribute_hidden = -1;
230 static int hf_smb_search_attribute_system = -1;
231 static int hf_smb_search_attribute_volume = -1;
232 static int hf_smb_search_attribute_directory = -1;
233 static int hf_smb_search_attribute_archive = -1;
234 static int hf_smb_access_mode = -1;
235 static int hf_smb_access_sharing = -1;
236 static int hf_smb_access_locality = -1;
237 static int hf_smb_access_caching = -1;
238 static int hf_smb_access_writetru = -1;
239 static int hf_smb_create_time = -1;
240 static int hf_smb_modify_time = -1;
241 static int hf_smb_backup_time = -1;
242 static int hf_smb_mac_alloc_block_count = -1;
243 static int hf_smb_mac_alloc_block_size = -1;
244 static int hf_smb_mac_free_block_count = -1;
245 static int hf_smb_mac_fndrinfo = -1;
246 static int hf_smb_mac_root_file_count = -1;
247 static int hf_smb_mac_root_dir_count = -1;
248 static int hf_smb_mac_file_count = -1;
249 static int hf_smb_mac_dir_count = -1;
250 static int hf_smb_mac_support_flags = -1;
251 static int hf_smb_mac_sup_access_ctrl = -1;
252 static int hf_smb_mac_sup_getset_comments = -1;
253 static int hf_smb_mac_sup_desktopdb_calls = -1;
254 static int hf_smb_mac_sup_unique_ids = -1;
255 static int hf_smb_mac_sup_streams = -1;
256 static int hf_smb_create_dos_date = -1;
257 static int hf_smb_create_dos_time = -1;
258 static int hf_smb_last_write_time = -1;
259 static int hf_smb_last_write_dos_date = -1;
260 static int hf_smb_last_write_dos_time = -1;
261 static int hf_smb_access_time = -1;
262 static int hf_smb_access_dos_date = -1;
263 static int hf_smb_access_dos_time = -1;
264 static int hf_smb_old_file_name = -1;
265 static int hf_smb_offset = -1;
266 static int hf_smb_remaining = -1;
267 static int hf_smb_padding = -1;
268 static int hf_smb_file_data = -1;
269 static int hf_smb_total_data_len = -1;
270 static int hf_smb_data_len = -1;
271 static int hf_smb_seek_mode = -1;
272 static int hf_smb_data_size = -1;
273 static int hf_smb_alloc_size = -1;
274 static int hf_smb_alloc_size64 = -1;
275 static int hf_smb_max_count = -1;
276 static int hf_smb_min_count = -1;
277 static int hf_smb_timeout = -1;
278 static int hf_smb_high_offset = -1;
279 static int hf_smb_units = -1;
280 static int hf_smb_bpu = -1;
281 static int hf_smb_blocksize = -1;
282 static int hf_smb_freeunits = -1;
283 static int hf_smb_data_offset = -1;
284 static int hf_smb_dcm = -1;
285 static int hf_smb_request_mask = -1;
286 static int hf_smb_response_mask = -1;
287 static int hf_smb_search_id = -1;
288 static int hf_smb_write_mode_write_through = -1;
289 static int hf_smb_write_mode_return_remaining = -1;
290 static int hf_smb_write_mode_raw = -1;
291 static int hf_smb_write_mode_message_start = -1;
292 static int hf_smb_write_mode_connectionless = -1;
293 static int hf_smb_resume_key_len = -1;
294 static int hf_smb_resume_find_id = -1;
295 static int hf_smb_resume_server_cookie = -1;
296 static int hf_smb_resume_client_cookie = -1;
297 static int hf_smb_andxoffset = -1;
298 static int hf_smb_lock_type_large = -1;
299 static int hf_smb_lock_type_cancel = -1;
300 static int hf_smb_lock_type_change = -1;
301 static int hf_smb_lock_type_oplock = -1;
302 static int hf_smb_lock_type_shared = -1;
303 static int hf_smb_locking_ol = -1;
304 static int hf_smb_number_of_locks = -1;
305 static int hf_smb_number_of_unlocks = -1;
306 static int hf_smb_lock_long_offset = -1;
307 static int hf_smb_lock_long_length = -1;
308 static int hf_smb_file_type = -1;
309 static int hf_smb_ipc_state_nonblocking = -1;
310 static int hf_smb_ipc_state_endpoint = -1;
311 static int hf_smb_ipc_state_pipe_type = -1;
312 static int hf_smb_ipc_state_read_mode = -1;
313 static int hf_smb_ipc_state_icount = -1;
314 static int hf_smb_server_fid = -1;
315 static int hf_smb_open_flags_add_info = -1;
316 static int hf_smb_open_flags_ex_oplock = -1;
317 static int hf_smb_open_flags_batch_oplock = -1;
318 static int hf_smb_open_flags_ealen = -1;
319 static int hf_smb_open_action_open = -1;
320 static int hf_smb_open_action_lock = -1;
321 static int hf_smb_vc_num = -1;
322 static int hf_smb_account = -1;
323 static int hf_smb_os = -1;
324 static int hf_smb_lanman = -1;
325 static int hf_smb_setup_action_guest = -1;
326 static int hf_smb_fs = -1;
327 static int hf_smb_connect_flags_dtid = -1;
328 static int hf_smb_connect_support_search = -1;
329 static int hf_smb_connect_support_in_dfs = -1;
330 static int hf_smb_max_setup_count = -1;
331 static int hf_smb_total_param_count = -1;
332 static int hf_smb_total_data_count = -1;
333 static int hf_smb_max_param_count = -1;
334 static int hf_smb_max_data_count = -1;
335 static int hf_smb_param_disp16 = -1;
336 static int hf_smb_param_count16 = -1;
337 static int hf_smb_param_offset16 = -1;
338 static int hf_smb_param_disp32 = -1;
339 static int hf_smb_param_count32 = -1;
340 static int hf_smb_param_offset32 = -1;
341 static int hf_smb_data_disp16 = -1;
342 static int hf_smb_data_count16 = -1;
343 static int hf_smb_data_offset16 = -1;
344 static int hf_smb_data_disp32 = -1;
345 static int hf_smb_data_count32 = -1;
346 static int hf_smb_data_offset32 = -1;
347 static int hf_smb_setup_count = -1;
348 static int hf_smb_nt_trans_subcmd = -1;
349 static int hf_smb_nt_ioctl_function_code = -1;
350 static int hf_smb_nt_ioctl_isfsctl = -1;
351 static int hf_smb_nt_ioctl_flags_root_handle = -1;
352 static int hf_smb_nt_ioctl_data = -1;
353 #ifdef SMB_UNUSED_HANDLES
354 static int hf_smb_nt_security_information = -1;
355 #endif
356 static int hf_smb_nt_notify_action = -1;
357 static int hf_smb_nt_notify_watch_tree = -1;
358 static int hf_smb_nt_notify_stream_write = -1;
359 static int hf_smb_nt_notify_stream_size = -1;
360 static int hf_smb_nt_notify_stream_name = -1;
361 static int hf_smb_nt_notify_security = -1;
362 static int hf_smb_nt_notify_ea = -1;
363 static int hf_smb_nt_notify_creation = -1;
364 static int hf_smb_nt_notify_last_access = -1;
365 static int hf_smb_nt_notify_last_write = -1;
366 static int hf_smb_nt_notify_size = -1;
367 static int hf_smb_nt_notify_attributes = -1;
368 static int hf_smb_nt_notify_dir_name = -1;
369 static int hf_smb_nt_notify_file_name = -1;
370 static int hf_smb_root_dir_fid = -1;
371 static int hf_smb_nt_create_disposition = -1;
372 static int hf_smb_sd_length = -1;
373 static int hf_smb_ea_length = -1;
374 static int hf_smb_file_name_len = -1;
375 static int hf_smb_nt_impersonation_level = -1;
376 static int hf_smb_nt_security_flags_context_tracking = -1;
377 static int hf_smb_nt_security_flags_effective_only = -1;
378 static int hf_smb_nt_access_mask_generic_read = -1;
379 static int hf_smb_nt_access_mask_generic_write = -1;
380 static int hf_smb_nt_access_mask_generic_execute = -1;
381 static int hf_smb_nt_access_mask_generic_all = -1;
382 static int hf_smb_nt_access_mask_maximum_allowed = -1;
383 static int hf_smb_nt_access_mask_system_security = -1;
384 static int hf_smb_nt_access_mask_synchronize = -1;
385 static int hf_smb_nt_access_mask_write_owner = -1;
386 static int hf_smb_nt_access_mask_write_dac = -1;
387 static int hf_smb_nt_access_mask_read_control = -1;
388 static int hf_smb_nt_access_mask_delete = -1;
389 static int hf_smb_nt_access_mask_write_attributes = -1;
390 static int hf_smb_nt_access_mask_read_attributes = -1;
391 static int hf_smb_nt_access_mask_delete_child = -1;
392 static int hf_smb_nt_access_mask_execute = -1;
393 static int hf_smb_nt_access_mask_write_ea = -1;
394 static int hf_smb_nt_access_mask_read_ea = -1;
395 static int hf_smb_nt_access_mask_append = -1;
396 static int hf_smb_nt_access_mask_write = -1;
397 static int hf_smb_nt_access_mask_read = -1;
398 static int hf_smb_nt_create_bits_oplock = -1;
399 static int hf_smb_nt_create_bits_boplock = -1;
400 static int hf_smb_nt_create_bits_dir = -1;
401 static int hf_smb_nt_create_bits_ext_resp = -1;
402 static int hf_smb_nt_create_options_directory_file = -1;
403 static int hf_smb_nt_create_options_write_through = -1;
404 static int hf_smb_nt_create_options_sequential_only = -1;
405 static int hf_smb_nt_create_options_sync_io_alert = -1;
406 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
407 static int hf_smb_nt_create_options_non_directory_file = -1;
408 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
409 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
410 static int hf_smb_nt_create_options_random_access = -1;
411 static int hf_smb_nt_create_options_delete_on_close = -1;
412 static int hf_smb_nt_share_access_read = -1;
413 static int hf_smb_nt_share_access_write = -1;
414 static int hf_smb_nt_share_access_delete = -1;
415 static int hf_smb_file_eattr_read_only = -1;
416 static int hf_smb_file_eattr_hidden = -1;
417 static int hf_smb_file_eattr_system = -1;
418 static int hf_smb_file_eattr_volume = -1;
419 static int hf_smb_file_eattr_directory = -1;
420 static int hf_smb_file_eattr_archive = -1;
421 static int hf_smb_file_eattr_device = -1;
422 static int hf_smb_file_eattr_normal = -1;
423 static int hf_smb_file_eattr_temporary = -1;
424 static int hf_smb_file_eattr_sparse = -1;
425 static int hf_smb_file_eattr_reparse = -1;
426 static int hf_smb_file_eattr_compressed = -1;
427 static int hf_smb_file_eattr_offline = -1;
428 static int hf_smb_file_eattr_not_content_indexed = -1;
429 static int hf_smb_file_eattr_encrypted = -1;
430 static int hf_smb_sec_desc_len = -1;
431 static int hf_smb_sec_desc_revision = -1;
432 static int hf_smb_sec_desc_type_owner_defaulted = -1;
433 static int hf_smb_sec_desc_type_group_defaulted = -1;
434 static int hf_smb_sec_desc_type_dacl_present = -1;
435 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
436 static int hf_smb_sec_desc_type_sacl_present = -1;
437 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
438 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
439 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
440 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
441 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
442 static int hf_smb_sec_desc_type_dacl_protected = -1;
443 static int hf_smb_sec_desc_type_sacl_protected = -1;
444 static int hf_smb_sec_desc_type_self_relative = -1;
445 static int hf_smb_sid = -1;
446 static int hf_smb_sid_revision = -1;
447 static int hf_smb_sid_num_auth = -1;
448 static int hf_smb_acl_revision = -1;
449 static int hf_smb_acl_size = -1;
450 static int hf_smb_acl_num_aces = -1;
451 static int hf_smb_ace_type = -1;
452 static int hf_smb_ace_size = -1;
453 static int hf_smb_ace_flags_object_inherit = -1;
454 static int hf_smb_ace_flags_container_inherit = -1;
455 static int hf_smb_ace_flags_non_propagate_inherit = -1;
456 static int hf_smb_ace_flags_inherit_only = -1;
457 static int hf_smb_ace_flags_inherited_ace = -1;
458 static int hf_smb_ace_flags_successful_access = -1;
459 static int hf_smb_ace_flags_failed_access = -1;
460 static int hf_smb_nt_qsd_owner = -1;
461 static int hf_smb_nt_qsd_group = -1;
462 static int hf_smb_nt_qsd_dacl = -1;
463 static int hf_smb_nt_qsd_sacl = -1;
464 static int hf_smb_extended_attributes = -1;
465 static int hf_smb_oplock_level = -1;
466 static int hf_smb_create_action = -1;
467 static int hf_smb_file_id = -1;
468 static int hf_smb_ea_error_offset = -1;
469 static int hf_smb_end_of_file = -1;
470 static int hf_smb_device_type = -1;
471 static int hf_smb_is_directory = -1;
472 static int hf_smb_next_entry_offset = -1;
473 static int hf_smb_change_time = -1;
474 static int hf_smb_setup_len = -1;
475 static int hf_smb_print_mode = -1;
476 static int hf_smb_print_identifier = -1;
477 static int hf_smb_restart_index = -1;
478 static int hf_smb_print_queue_date = -1;
479 static int hf_smb_print_queue_dos_date = -1;
480 static int hf_smb_print_queue_dos_time = -1;
481 static int hf_smb_print_status = -1;
482 static int hf_smb_print_spool_file_number = -1;
483 static int hf_smb_print_spool_file_size = -1;
484 static int hf_smb_print_spool_file_name = -1;
485 static int hf_smb_start_index = -1;
486 static int hf_smb_originator_name = -1;
487 static int hf_smb_destination_name = -1;
488 static int hf_smb_message_len = -1;
489 static int hf_smb_message = -1;
490 static int hf_smb_mgid = -1;
491 static int hf_smb_forwarded_name = -1;
492 static int hf_smb_machine_name = -1;
493 static int hf_smb_cancel_to = -1;
494 static int hf_smb_trans2_subcmd = -1;
495 static int hf_smb_trans_name = -1;
496 static int hf_smb_transaction_flags_dtid = -1;
497 static int hf_smb_transaction_flags_owt = -1;
498 static int hf_smb_search_count = -1;
499 static int hf_smb_search_pattern = -1;
500 static int hf_smb_ff2_backup = -1;
501 static int hf_smb_ff2_continue = -1;
502 static int hf_smb_ff2_resume = -1;
503 static int hf_smb_ff2_close_eos = -1;
504 static int hf_smb_ff2_close = -1;
505 static int hf_smb_ff2_information_level = -1;
506 static int hf_smb_qpi_loi = -1;
507 #if 0
508 static int hf_smb_sfi_writetru = -1;
509 static int hf_smb_sfi_caching = -1;
510 #endif
511 static int hf_smb_storage_type = -1;
512 static int hf_smb_resume = -1;
513 static int hf_smb_max_referral_level = -1;
514 static int hf_smb_qfsi_information_level = -1;
515 static int hf_smb_ea_size = -1;
516 static int hf_smb_list_length = -1;
517 static int hf_smb_number_of_links = -1;
518 static int hf_smb_delete_pending = -1;
519 static int hf_smb_index_number = -1;
520 static int hf_smb_current_offset = -1;
521 static int hf_smb_t2_alignment = -1;
522 static int hf_smb_t2_stream_name_length = -1;
523 static int hf_smb_t2_stream_size = -1;
524 static int hf_smb_t2_stream_name = -1;
525 static int hf_smb_t2_compressed_file_size = -1;
526 static int hf_smb_t2_compressed_format = -1;
527 static int hf_smb_t2_compressed_unit_shift = -1;
528 static int hf_smb_t2_compressed_chunk_shift = -1;
529 static int hf_smb_t2_compressed_cluster_shift = -1;
530 static int hf_smb_dfs_path_consumed = -1;
531 static int hf_smb_dfs_num_referrals = -1;
532 static int hf_smb_get_dfs_server_hold_storage = -1;
533 static int hf_smb_get_dfs_fielding = -1;
534 static int hf_smb_dfs_referral_version = -1;
535 static int hf_smb_dfs_referral_size = -1;
536 static int hf_smb_dfs_referral_server_type = -1;
537 static int hf_smb_dfs_referral_flags_strip = -1;
538 static int hf_smb_dfs_referral_node_offset = -1;
539 static int hf_smb_dfs_referral_node = -1;
540 static int hf_smb_dfs_referral_proximity = -1;
541 static int hf_smb_dfs_referral_ttl = -1;
542 static int hf_smb_dfs_referral_path_offset = -1;
543 static int hf_smb_dfs_referral_path = -1;
544 static int hf_smb_dfs_referral_alt_path_offset = -1;
545 static int hf_smb_dfs_referral_alt_path = -1;
546 static int hf_smb_end_of_search = -1;
547 static int hf_smb_last_name_offset = -1;
548 static int hf_smb_fn_information_level = -1;
549 static int hf_smb_monitor_handle = -1;
550 static int hf_smb_change_count = -1;
551 static int hf_smb_file_index = -1;
552 static int hf_smb_short_file_name = -1;
553 static int hf_smb_short_file_name_len = -1;
554 static int hf_smb_fs_id = -1;
555 static int hf_smb_sector_unit = -1;
556 static int hf_smb_fs_units = -1;
557 static int hf_smb_fs_sector = -1;
558 static int hf_smb_avail_units = -1;
559 static int hf_smb_volume_serial_num = -1;
560 static int hf_smb_volume_label_len = -1;
561 static int hf_smb_volume_label = -1;
562 static int hf_smb_free_alloc_units64 = -1;
563 static int hf_smb_caller_free_alloc_units64 = -1;
564 static int hf_smb_actual_free_alloc_units64 = -1;
565 static int hf_smb_max_name_len = -1;
566 static int hf_smb_fs_name_len = -1;
567 static int hf_smb_fs_name = -1;
568 static int hf_smb_device_char_removable = -1;
569 static int hf_smb_device_char_read_only = -1;
570 static int hf_smb_device_char_floppy = -1;
571 static int hf_smb_device_char_write_once = -1;
572 static int hf_smb_device_char_remote = -1;
573 static int hf_smb_device_char_mounted = -1;
574 static int hf_smb_device_char_virtual = -1;
575 static int hf_smb_fs_attr_css = -1;
576 static int hf_smb_fs_attr_cpn = -1;
577 static int hf_smb_fs_attr_pacls = -1;
578 static int hf_smb_fs_attr_fc = -1;
579 static int hf_smb_fs_attr_vq = -1;
580 static int hf_smb_fs_attr_dim = -1;
581 static int hf_smb_fs_attr_vic = -1;
582 static int hf_smb_quota_flags_enabled = -1;
583 static int hf_smb_quota_flags_deny_disk = -1;
584 static int hf_smb_quota_flags_log_limit = -1;
585 static int hf_smb_quota_flags_log_warning = -1;
586 static int hf_smb_soft_quota_limit = -1;
587 static int hf_smb_hard_quota_limit = -1;
588 static int hf_smb_user_quota_used = -1;
589 static int hf_smb_user_quota_offset = -1;
590 static int hf_smb_nt_rename_level = -1;
591 static int hf_smb_cluster_count = -1;
592 static int hf_smb_segments = -1;
593 static int hf_smb_segment = -1;
594 static int hf_smb_segment_overlap = -1;
595 static int hf_smb_segment_overlap_conflict = -1;
596 static int hf_smb_segment_multiple_tails = -1;
597 static int hf_smb_segment_too_long_fragment = -1;
598 static int hf_smb_segment_error = -1;
599 static int hf_smb_pipe_write_len = -1;
600
601 static gint ett_smb = -1;
602 static gint ett_smb_hdr = -1;
603 static gint ett_smb_command = -1;
604 static gint ett_smb_fileattributes = -1;
605 static gint ett_smb_capabilities = -1;
606 static gint ett_smb_aflags = -1;
607 static gint ett_smb_dialect = -1;
608 static gint ett_smb_dialects = -1;
609 static gint ett_smb_mode = -1;
610 static gint ett_smb_rawmode = -1;
611 static gint ett_smb_flags = -1;
612 static gint ett_smb_flags2 = -1;
613 static gint ett_smb_desiredaccess = -1;
614 static gint ett_smb_search = -1;
615 static gint ett_smb_file = -1;
616 static gint ett_smb_openfunction = -1;
617 static gint ett_smb_filetype = -1;
618 static gint ett_smb_openaction = -1;
619 static gint ett_smb_writemode = -1;
620 static gint ett_smb_lock_type = -1;
621 static gint ett_smb_ssetupandxaction = -1;
622 static gint ett_smb_optionsup = -1;
623 static gint ett_smb_time_date = -1;
624 static gint ett_smb_move_copy_flags = -1;
625 static gint ett_smb_file_attributes = -1;
626 static gint ett_smb_search_resume_key = -1;
627 static gint ett_smb_search_dir_info = -1;
628 static gint ett_smb_unlocks = -1;
629 static gint ett_smb_unlock = -1;
630 static gint ett_smb_locks = -1;
631 static gint ett_smb_lock = -1;
632 static gint ett_smb_open_flags = -1;
633 static gint ett_smb_ipc_state = -1;
634 static gint ett_smb_open_action = -1;
635 static gint ett_smb_setup_action = -1;
636 static gint ett_smb_connect_flags = -1;
637 static gint ett_smb_connect_support_bits = -1;
638 static gint ett_smb_nt_access_mask = -1;
639 static gint ett_smb_nt_create_bits = -1;
640 static gint ett_smb_nt_create_options = -1;
641 static gint ett_smb_nt_share_access = -1;
642 static gint ett_smb_nt_security_flags = -1;
643 static gint ett_smb_nt_trans_setup = -1;
644 static gint ett_smb_nt_trans_data = -1;
645 static gint ett_smb_nt_trans_param = -1;
646 static gint ett_smb_nt_notify_completion_filter = -1;
647 static gint ett_smb_nt_ioctl_flags = -1;
648 static gint ett_smb_security_information_mask = -1;
649 static gint ett_smb_print_queue_entry = -1;
650 static gint ett_smb_transaction_flags = -1;
651 static gint ett_smb_transaction_params = -1;
652 static gint ett_smb_find_first2_flags = -1;
653 static gint ett_smb_mac_support_flags = -1;
654 #if 0
655 static gint ett_smb_ioflag = -1;
656 #endif
657 static gint ett_smb_transaction_data = -1;
658 static gint ett_smb_stream_info = -1;
659 static gint ett_smb_dfs_referrals = -1;
660 static gint ett_smb_dfs_referral = -1;
661 static gint ett_smb_dfs_referral_flags = -1;
662 static gint ett_smb_get_dfs_flags = -1;
663 static gint ett_smb_ff2_data = -1;
664 static gint ett_smb_device_characteristics = -1;
665 static gint ett_smb_fs_attributes = -1;
666 static gint ett_smb_segments = -1;
667 static gint ett_smb_segment = -1;
668 static gint ett_smb_sec_desc = -1;
669 static gint ett_smb_sid = -1;
670 static gint ett_smb_acl = -1;
671 static gint ett_smb_ace = -1;
672 static gint ett_smb_ace_flags = -1;
673 static gint ett_smb_sec_desc_type = -1;
674 static gint ett_smb_quotaflags = -1;
675 static gint ett_smb_secblob = -1;
676 static gint ett_smb_unicode_password = -1;
677
678 static int smb_tap = -1;
679
680 static dissector_handle_t gssapi_handle = NULL;
681 static dissector_handle_t ntlmssp_handle = NULL;
682
683 static const fragment_items smb_frag_items = {
684         &ett_smb_segment,
685         &ett_smb_segments,
686
687         &hf_smb_segments,
688         &hf_smb_segment,
689         &hf_smb_segment_overlap,
690         &hf_smb_segment_overlap_conflict,
691         &hf_smb_segment_multiple_tails,
692         &hf_smb_segment_too_long_fragment,
693         &hf_smb_segment_error,
694         NULL,
695
696         "segments"
697 };
698
699 proto_tree *top_tree=NULL;     /* ugly */
700
701 static char *decode_smb_name(unsigned char);
702 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
703
704 /*
705  * Macros for use in the main dissector routines for an SMB.
706  */
707
708 #define WORD_COUNT      \
709         /* Word Count */                                \
710         wc = tvb_get_guint8(tvb, offset);               \
711         proto_tree_add_uint(tree, hf_smb_word_count,    \
712                 tvb, offset, 1, wc);                    \
713         offset += 1;                                    \
714         if(wc==0) goto bytecount;
715
716 #define BYTE_COUNT      \
717         bytecount:                                      \
718         bc = tvb_get_letohs(tvb, offset);               \
719         proto_tree_add_uint(tree, hf_smb_byte_count,    \
720                         tvb, offset, 2, bc);            \
721         offset += 2;                                    \
722         if(bc==0) goto endofcommand;
723
724 #define CHECK_BYTE_COUNT(len)   \
725         if (bc < len) goto endofcommand;
726
727 #define COUNT_BYTES(len)   {\
728         int tmp;            \
729         tmp=len;            \
730         offset += tmp;      \
731         bc -= tmp;          \
732         }
733
734 #define END_OF_SMB      \
735         if (bc != 0) { \
736                 proto_tree_add_text(tree, tvb, offset, bc, \
737                     "Extra byte parameters");           \
738                 offset += bc;                           \
739         }                                               \
740         endofcommand:
741
742 /*
743  * Macros for use in routines called by them.
744  */
745 #define CHECK_BYTE_COUNT_SUBR(len)      \
746         if (*bcp < len) {               \
747                 *trunc = TRUE;          \
748                 return offset;          \
749         }
750
751 #define CHECK_STRING_SUBR(fn)   \
752         if (fn == NULL) {       \
753                 *trunc = TRUE;  \
754                 return offset;  \
755         }
756
757 #define COUNT_BYTES_SUBR(len)   \
758         offset += len;          \
759         *bcp -= len;
760
761 /*
762  * Macros for use when dissecting transaction parameters and data
763  */
764 #define CHECK_BYTE_COUNT_TRANS(len)     \
765         if (bc < len) return offset;
766
767 #define CHECK_STRING_TRANS(fn)  \
768         if (fn == NULL) return offset;
769
770 #define COUNT_BYTES_TRANS(len)  \
771         offset += len;          \
772         bc -= len;
773
774 /*
775  * Macros for use in subrroutines dissecting transaction parameters or data
776  */
777 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
778         if (*bcp < len) return offset;
779
780 #define CHECK_STRING_TRANS_SUBR(fn)     \
781         if (fn == NULL) return offset;
782
783 #define COUNT_BYTES_TRANS_SUBR(len)     \
784         offset += len;                  \
785         *bcp -= len;
786
787
788 gboolean sid_name_snooping = FALSE;
789
790 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
791    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
792    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
793 static gboolean smb_trans_reassembly = FALSE;
794 gboolean smb_dcerpc_reassembly = FALSE;
795
796 static GHashTable *smb_trans_fragment_table = NULL;
797
798 static void
799 smb_trans_reassembly_init(void)
800 {
801         fragment_table_init(&smb_trans_fragment_table);
802 }
803
804 static fragment_data *
805 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
806                      int offset, int count, int pos, int totlen)
807 {
808         fragment_data *fd_head=NULL;
809         smb_info_t *si;
810         int more_frags;
811
812         more_frags=totlen>(pos+count);
813
814         si = (smb_info_t *)pinfo->private_data;
815         if (si->sip == NULL) {
816                 /*
817                  * We don't have the frame number of the request.
818                  *
819                  * XXX - is there truly nothing we can do here?
820                  * Can we not separately keep track of the original
821                  * transaction and its continuations, as we did
822                  * at one time?
823                  *
824                  * It is probably not much point in even trying to do something here
825                  * if we have never seen the initial request. Without the initial
826                  * request we probably miss all parameters and the begining of data
827                  * so we cant even call a subdissector since we can not determine
828                  * which type of transaction call this is.
829                  */
830                 return NULL;
831         }
832
833         if(!pinfo->fd->flags.visited){
834                 fd_head = fragment_add(tvb, offset, pinfo,
835                                        si->sip->frame_req, smb_trans_fragment_table,
836                                        pos, count, more_frags);
837         } else {
838                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
839         }
840
841         /* we only show the defragmented packet for the first fragment,
842            or else we might end up with dissecting one HUGE transaction PDU
843            a LOT of times. (first fragment is the only one containing the setup
844            bytes)
845            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
846            SMBs. Takes a LOT of time dissecting and is not fun.
847         */
848         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
849                 return fd_head;
850         } else {
851                 return NULL;
852         }
853 }
854
855
856
857
858
859 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
860    These variables and functions are used to match
861    responses with calls
862    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
863 /*
864  * The information we need to save about a request in order to show the
865  * frame number of the request in the dissection of the reply.
866  */
867 typedef struct  {
868         guint32 frame;
869         guint32 pid_mid;
870 } smb_saved_info_key_t;
871
872 static GMemChunk *smb_saved_info_key_chunk = NULL;
873 static GMemChunk *smb_saved_info_chunk = NULL;
874 static int smb_saved_info_init_count = 200;
875
876 /* unmatched smb_saved_info structures.
877    For unmatched smb_saved_info structures we store the smb_saved_info
878    structure using the MID and the PID as the key.
879
880    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
881    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
882    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
883 */
884 static gint
885 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
886 {
887         register guint32 key1 = (guint32)k1;
888         register guint32 key2 = (guint32)k2;
889         return key1==key2;
890 }
891 static guint
892 smb_saved_info_hash_unmatched(gconstpointer k)
893 {
894         register guint32 key = (guint32)k;
895         return key;
896 }
897
898 /* matched smb_saved_info structures.
899    For matched smb_saved_info structures we store the smb_saved_info
900    structure twice in the table using the frame number, and a combination
901    of the MID and the PID, as the key.
902    The frame number is guaranteed to be unique but if ever someone makes
903    some change that will renumber the frames in a capture we are in BIG trouble.
904    This is not likely though since that would break (among other things) all the
905    reassembly routines as well.
906
907    We also need the MID as there may be more than one SMB request or reply
908    in a single frame, and we also need the PID as there may be more than
909    one outstanding request with the same MID and different PIDs.
910 */
911 static gint
912 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
913 {
914         const smb_saved_info_key_t *key1 = k1;
915         const smb_saved_info_key_t *key2 = k2;
916         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
917 }
918 static guint
919 smb_saved_info_hash_matched(gconstpointer k)
920 {
921         const smb_saved_info_key_t *key = k;
922         return key->frame + key->pid_mid;
923 }
924
925 static GMemChunk *smb_nt_transact_info_chunk = NULL;
926 static int smb_nt_transact_info_init_count = 200;
927
928 static GMemChunk *smb_transact2_info_chunk = NULL;
929 static int smb_transact2_info_init_count = 200;
930
931 /*
932  * The information we need to save about a Transaction request in order
933  * to dissect the reply; this includes information for use by the
934  * Remote API dissector.
935  */
936 static GMemChunk *smb_transact_info_chunk = NULL;
937 static int smb_transact_info_init_count = 200;
938
939 static GMemChunk *conv_tables_chunk = NULL;
940 static GSList *conv_tables = NULL;
941 static int conv_tables_count = 10;
942
943
944 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
945    End of request/response matching functions
946    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
947
948 static const value_string buffer_format_vals[] = {
949         {1,     "Data Block"},
950         {2,     "Dialect"},
951         {3,     "Pathname"},
952         {4,     "ASCII"},
953         {5,     "Variable Block"},
954         {0,     NULL}
955 };
956
957 /*
958  * UTIME - this is *almost* like a UNIX time stamp, except that it's
959  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
960  * January 1, 1970, 00:00:00 GMT.
961  *
962  * This means we have to do some extra work to convert it.  This code is
963  * based on the Samba code:
964  *
965  *      Unix SMB/Netbios implementation.
966  *      Version 1.9.
967  *      time handling functions
968  *      Copyright (C) Andrew Tridgell 1992-1998
969  */
970
971 /*
972  * Yield the difference between *A and *B, in seconds, ignoring leap
973  * seconds.
974  */
975 #define TM_YEAR_BASE 1900
976
977 static int
978 tm_diff(struct tm *a, struct tm *b)
979 {
980         int ay = a->tm_year + (TM_YEAR_BASE - 1);
981         int by = b->tm_year + (TM_YEAR_BASE - 1);
982         int intervening_leap_days =
983             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
984         int years = ay - by;
985         int days =
986             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
987         int hours = 24*days + (a->tm_hour - b->tm_hour);
988         int minutes = 60*hours + (a->tm_min - b->tm_min);
989         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
990
991         return seconds;
992 }
993
994 /*
995  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
996  * determined.
997  */
998 static int
999 TimeZone(time_t t)
1000 {
1001         struct tm *tm = gmtime(&t);
1002         struct tm tm_utc;
1003
1004         if (tm == NULL)
1005                 return 0;
1006         tm_utc = *tm;
1007         tm = localtime(&t);
1008         if (tm == NULL)
1009                 return 0;
1010         return tm_diff(&tm_utc,tm);
1011 }
1012
1013 /*
1014  * Return the same value as TimeZone, but it should be more efficient.
1015  *
1016  * We keep a table of DST offsets to prevent calling localtime() on each
1017  * call of this function. This saves a LOT of time on many unixes.
1018  *
1019  * Updated by Paul Eggert <eggert@twinsun.com>
1020  */
1021 #ifndef CHAR_BIT
1022 #define CHAR_BIT 8
1023 #endif
1024
1025 #ifndef TIME_T_MIN
1026 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1027                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1028 #endif
1029 #ifndef TIME_T_MAX
1030 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1031 #endif
1032
1033 static int
1034 TimeZoneFaster(time_t t)
1035 {
1036         static struct dst_table {time_t start,end; int zone;} *tdt;
1037         static struct dst_table *dst_table = NULL;
1038         static int table_size = 0;
1039         int i;
1040         int zone = 0;
1041
1042         if (t == 0)
1043                 t = time(NULL);
1044
1045         /* Tunis has a 8 day DST region, we need to be careful ... */
1046 #define MAX_DST_WIDTH (365*24*60*60)
1047 #define MAX_DST_SKIP (7*24*60*60)
1048
1049         for (i = 0; i < table_size; i++) {
1050                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1051                         break;
1052         }
1053
1054         if (i < table_size) {
1055                 zone = dst_table[i].zone;
1056         } else {
1057                 time_t low,high;
1058
1059                 zone = TimeZone(t);
1060                 if (dst_table == NULL)
1061                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1062                 else
1063                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1064                 if (tdt == NULL) {
1065                         if (dst_table)
1066                                 g_free(dst_table);
1067                         table_size = 0;
1068                 } else {
1069                         dst_table = tdt;
1070                         table_size++;
1071
1072                         dst_table[i].zone = zone;
1073                         dst_table[i].start = dst_table[i].end = t;
1074
1075                         /* no entry will cover more than 6 months */
1076                         low = t - MAX_DST_WIDTH/2;
1077                         if (t < low)
1078                                 low = TIME_T_MIN;
1079
1080                         high = t + MAX_DST_WIDTH/2;
1081                         if (high < t)
1082                                 high = TIME_T_MAX;
1083
1084                         /*
1085                          * Widen the new entry using two bisection searches.
1086                          */
1087                         while (low+60*60 < dst_table[i].start) {
1088                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1089                                         t = dst_table[i].start - MAX_DST_SKIP;
1090                                 else
1091                                         t = low + (dst_table[i].start-low)/2;
1092                                 if (TimeZone(t) == zone)
1093                                         dst_table[i].start = t;
1094                                 else
1095                                         low = t;
1096                         }
1097
1098                         while (high-60*60 > dst_table[i].end) {
1099                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1100                                         t = dst_table[i].end + MAX_DST_SKIP;
1101                                 else
1102                                         t = high - (high-dst_table[i].end)/2;
1103                                 if (TimeZone(t) == zone)
1104                                         dst_table[i].end = t;
1105                                 else
1106                                         high = t;
1107                         }
1108                 }
1109         }
1110         return zone;
1111 }
1112
1113 /*
1114  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1115  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1116  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1117  * daylight savings transitions because some local times are ambiguous.
1118  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1119  */
1120 static int
1121 LocTimeDiff(time_t lt)
1122 {
1123         int d = TimeZoneFaster(lt);
1124         time_t t = lt + d;
1125
1126         /* if overflow occurred, ignore all the adjustments so far */
1127         if (((t < lt) ^ (d < 0)))
1128                 t = lt;
1129
1130         /*
1131          * Now t should be close enough to the true UTC to yield the
1132          * right answer.
1133          */
1134         return TimeZoneFaster(t);
1135 }
1136
1137 static int
1138 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1139 {
1140         guint32 timeval;
1141         nstime_t ts;
1142
1143         timeval = tvb_get_letohl(tvb, offset);
1144         if (timeval == 0xffffffff) {
1145                 proto_tree_add_text(tree, tvb, offset, 4,
1146                     "%s: No time specified (0xffffffff)",
1147                     proto_registrar_get_name(hf_date));
1148                 offset += 4;
1149                 return offset;
1150         }
1151
1152         /*
1153          * We add the local time offset.
1154          */
1155         ts.secs = timeval + LocTimeDiff(timeval);
1156         ts.nsecs = 0;
1157
1158         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1159         offset += 4;
1160
1161         return offset;
1162 }
1163
1164 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1165
1166 /*
1167  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1168  * to an "nstime_t".
1169  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1170  * midnight "UTC", in 100ns units.
1171  * Return TRUE if the conversion succeeds, FALSE otherwise.
1172  *
1173  * According to the Samba code, it appears to be kludge-GMT (at least for
1174  * file listings). This means it's the GMT you get by taking a local time
1175  * and adding the server time zone offset.  This is NOT the same as GMT in
1176  * some cases.   However, we don't know the server time zone, so we don't
1177  * do that adjustment.
1178  *
1179  * This code is based on the Samba code:
1180  *
1181  *      Unix SMB/Netbios implementation.
1182  *      Version 1.9.
1183  *      time handling functions
1184  *      Copyright (C) Andrew Tridgell 1992-1998
1185  */
1186 static gboolean
1187 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1188 {
1189         double d;
1190         /* The next two lines are a fix needed for the
1191             broken SCO compiler. JRA. */
1192         time_t l_time_min = TIME_T_MIN;
1193         time_t l_time_max = TIME_T_MAX;
1194
1195         if (filetime_high == 0)
1196                 return FALSE;
1197
1198         /*
1199          * Get the time as a double, in seconds and fractional seconds.
1200          */
1201         d = ((double)filetime_high)*4.0*(double)(1<<30);
1202         d += filetime_low;
1203         d *= 1.0e-7;
1204
1205         /* Now adjust by 369 years, to make the seconds since 1970. */
1206         d -= TIME_FIXUP_CONSTANT;
1207
1208         if (!(l_time_min <= d && d <= l_time_max))
1209                 return FALSE;
1210
1211         /*
1212          * Get the time as seconds and nanoseconds.
1213          */
1214         tv->secs = d;
1215         tv->nsecs = (d - tv->secs)*1000000000;
1216
1217         return TRUE;
1218 }
1219
1220 int
1221 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1222 {
1223         guint32 filetime_high, filetime_low;
1224         nstime_t ts;
1225
1226         /* XXX there seems also to be another special time value which is fairly common :
1227            0x40000000 00000000
1228            the meaning of this one is yet unknown
1229         */
1230         if (tree) {
1231                 filetime_low = tvb_get_letohl(tvb, offset);
1232                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1233                 if (filetime_low == 0 && filetime_high == 0) {
1234                         proto_tree_add_text(tree, tvb, offset, 8,
1235                             "%s: No time specified (0)",
1236                             proto_registrar_get_name(hf_date));
1237                 } else if(filetime_low==0 && filetime_high==0x80000000){
1238                         proto_tree_add_text(tree, tvb, offset, 8,
1239                             "%s: Infinity (relative time)",
1240                             proto_registrar_get_name(hf_date));
1241                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1242                         proto_tree_add_text(tree, tvb, offset, 8,
1243                             "%s: Infinity (absolute time)",
1244                             proto_registrar_get_name(hf_date));
1245                 } else {
1246                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1247                                 proto_tree_add_time(tree, hf_date, tvb,
1248                                     offset, 8, &ts);
1249                         } else {
1250                                 proto_tree_add_text(tree, tvb, offset, 8,
1251                                     "%s: Time can't be converted",
1252                                     proto_registrar_get_name(hf_date));
1253                         }
1254                 }
1255         }
1256
1257         offset += 8;
1258         return offset;
1259 }
1260
1261 static int
1262 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1263     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1264 {
1265         guint16 dos_time, dos_date;
1266         proto_item *item = NULL;
1267         proto_tree *tree = NULL;
1268         struct tm tm;
1269         time_t t;
1270         static const int mday_noleap[12] = {
1271                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1272         };
1273         static const int mday_leap[12] = {
1274                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1275         };
1276 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1277         nstime_t tv;
1278
1279         if (time_first) {
1280                 dos_time = tvb_get_letohs(tvb, offset);
1281                 dos_date = tvb_get_letohs(tvb, offset+2);
1282         } else {
1283                 dos_date = tvb_get_letohs(tvb, offset);
1284                 dos_time = tvb_get_letohs(tvb, offset+2);
1285         }
1286
1287         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1288             (dos_date == 0 && dos_time == 0)) {
1289                 /*
1290                  * No date/time specified.
1291                  */
1292                 if(parent_tree){
1293                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1294                             "%s: No time specified (0x%08x)",
1295                             proto_registrar_get_name(hf_date),
1296                             (dos_date << 16) | dos_time);
1297                 }
1298                 offset += 4;
1299                 return offset;
1300         }
1301
1302         tm.tm_sec = (dos_time&0x1f)*2;
1303         tm.tm_min = (dos_time>>5)&0x3f;
1304         tm.tm_hour = (dos_time>>11)&0x1f;
1305         tm.tm_mday = dos_date&0x1f;
1306         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1307         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1308         tm.tm_isdst = -1;
1309
1310         /*
1311          * Do some sanity checks before calling "mktime()";
1312          * "mktime()" doesn't do them, it "normalizes" out-of-range
1313          * values.
1314          */
1315         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1316            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1317            (ISLEAP(tm.tm_year + 1900) ?
1318              tm.tm_mday > mday_leap[tm.tm_mon] :
1319              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1320              (t = mktime(&tm)) == -1) {
1321                 /*
1322                  * Invalid date/time.
1323                  */
1324                 if (parent_tree) {
1325                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1326                             "%s: Invalid time",
1327                             proto_registrar_get_name(hf_date));
1328                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1329                         if (time_first) {
1330                                 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);
1331                                 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);
1332                         } else {
1333                                 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);
1334                                 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);
1335                         }
1336                 }
1337                 offset += 4;
1338                 return offset;
1339         }
1340
1341         tv.secs = t;
1342         tv.nsecs = 0;
1343
1344         if(parent_tree){
1345                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1346                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1347                 if (time_first) {
1348                         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);
1349                         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);
1350                 } else {
1351                         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);
1352                         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);
1353                 }
1354         }
1355
1356         offset += 4;
1357
1358         return offset;
1359 }
1360
1361
1362 static const value_string da_access_vals[] = {
1363         { 0,            "Open for reading"},
1364         { 1,            "Open for writing"},
1365         { 2,            "Open for reading and writing"},
1366         { 3,            "Open for execute"},
1367         {0, NULL}
1368 };
1369 static const value_string da_sharing_vals[] = {
1370         { 0,            "Compatibility mode"},
1371         { 1,            "Deny read/write/execute (exclusive)"},
1372         { 2,            "Deny write"},
1373         { 3,            "Deny read/execute"},
1374         { 4,            "Deny none"},
1375         {0, NULL}
1376 };
1377 static const value_string da_locality_vals[] = {
1378         { 0,            "Locality of reference unknown"},
1379         { 1,            "Mainly sequential access"},
1380         { 2,            "Mainly random access"},
1381         { 3,            "Random access with some locality"},
1382         {0, NULL}
1383 };
1384 static const true_false_string tfs_da_caching = {
1385         "Do not cache this file",
1386         "Caching permitted on this file"
1387 };
1388 static const true_false_string tfs_da_writetru = {
1389         "Write through enabled",
1390         "Write through disabled"
1391 };
1392 static int
1393 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1394 {
1395         guint16 mask;
1396         proto_item *item = NULL;
1397         proto_tree *tree = NULL;
1398
1399         mask = tvb_get_letohs(tvb, offset);
1400
1401         if(parent_tree){
1402                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1403                         "%s Access: 0x%04x", type, mask);
1404                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1405         }
1406
1407         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1408                 tvb, offset, 2, mask);
1409         proto_tree_add_boolean(tree, hf_smb_access_caching,
1410                 tvb, offset, 2, mask);
1411         proto_tree_add_uint(tree, hf_smb_access_locality,
1412                 tvb, offset, 2, mask);
1413         proto_tree_add_uint(tree, hf_smb_access_sharing,
1414                 tvb, offset, 2, mask);
1415         proto_tree_add_uint(tree, hf_smb_access_mode,
1416                 tvb, offset, 2, mask);
1417
1418         offset += 2;
1419
1420         return offset;
1421 }
1422
1423 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1424 #define SMB_FILE_ATTRIBUTE_HIDDEN                       0x00000002
1425 #define SMB_FILE_ATTRIBUTE_SYSTEM                       0x00000004
1426 #define SMB_FILE_ATTRIBUTE_VOLUME                       0x00000008
1427 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1428 #define SMB_FILE_ATTRIBUTE_ARCHIVE                      0x00000020
1429 #define SMB_FILE_ATTRIBUTE_DEVICE                       0x00000040
1430 #define SMB_FILE_ATTRIBUTE_NORMAL                       0x00000080
1431 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1432 #define SMB_FILE_ATTRIBUTE_SPARSE                       0x00000200
1433 #define SMB_FILE_ATTRIBUTE_REPARSE                      0x00000400
1434 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1435 #define SMB_FILE_ATTRIBUTE_OFFLINE                      0x00001000
1436 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1437 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1438
1439 static const true_false_string tfs_file_attribute_read_only = {
1440         "This file is READ ONLY",
1441         "This file is NOT read only",
1442 };
1443 static const true_false_string tfs_file_attribute_hidden = {
1444         "This is a HIDDEN file",
1445         "This is NOT a hidden file"
1446 };
1447 static const true_false_string tfs_file_attribute_system = {
1448         "This is a SYSTEM file",
1449         "This is NOT a system file"
1450 };
1451 static const true_false_string tfs_file_attribute_volume = {
1452         "This is a VOLUME ID",
1453         "This is NOT a volume ID"
1454 };
1455 static const true_false_string tfs_file_attribute_directory = {
1456         "This is a DIRECTORY",
1457         "This is NOT a directory"
1458 };
1459 static const true_false_string tfs_file_attribute_archive = {
1460         "This file has been modified since last ARCHIVE",
1461         "This file has NOT been modified since last archive"
1462 };
1463 static const true_false_string tfs_file_attribute_device = {
1464         "This is a DEVICE",
1465         "This is NOT a device"
1466 };
1467 static const true_false_string tfs_file_attribute_normal = {
1468         "This file is an ordinary file",
1469         "This file has some attribute set"
1470 };
1471 static const true_false_string tfs_file_attribute_temporary = {
1472         "This is a TEMPORARY file",
1473         "This is NOT a temporary file"
1474 };
1475 static const true_false_string tfs_file_attribute_sparse = {
1476         "This is a SPARSE file",
1477         "This is NOT a sparse file"
1478 };
1479 static const true_false_string tfs_file_attribute_reparse = {
1480         "This file has an associated REPARSE POINT",
1481         "This file does NOT have an associated reparse point"
1482 };
1483 static const true_false_string tfs_file_attribute_compressed = {
1484         "This is a COMPRESSED file",
1485         "This is NOT a compressed file"
1486 };
1487 static const true_false_string tfs_file_attribute_offline = {
1488         "This file is OFFLINE",
1489         "This file is NOT offline"
1490 };
1491 static const true_false_string tfs_file_attribute_not_content_indexed = {
1492         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1493         "This file MAY be indexed by the content indexing service"
1494 };
1495 static const true_false_string tfs_file_attribute_encrypted = {
1496         "This is an ENCRYPTED file",
1497         "This is NOT an encrypted file"
1498 };
1499
1500 /*
1501  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1502  * listed as USHORT, and seem to be in packets in the wild, while in other
1503  * places they are listed as ULONG, and also seem to be.
1504  *
1505  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1506  * bytes to consume.
1507  */
1508
1509 static int
1510 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1511                         int bytes)
1512 {
1513         guint16 mask;
1514         proto_item *item = NULL;
1515         proto_tree *tree = NULL;
1516
1517         if (bytes != 2 && bytes != 4) {
1518
1519                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1520                 exit(1);
1521
1522         }
1523
1524         /*
1525          * The actual bits of interest appear to only be a USHORT
1526          */
1527         /* FIXME if this ever changes! */
1528         mask = tvb_get_letohs(tvb, offset);
1529
1530         if(parent_tree){
1531                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1532                         "File Attributes: 0x%08x", mask);
1533                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1534         }
1535         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1536                                tvb, offset, bytes, mask);       
1537         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1538                                tvb, offset, bytes, mask);
1539         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1540                                tvb, offset, bytes, mask);
1541         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1542                                tvb, offset, bytes, mask);
1543         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1544                                tvb, offset, bytes, mask);
1545         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1546                                tvb, offset, bytes, mask);
1547         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1548                                tvb, offset, bytes, mask);
1549         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1550                                tvb, offset, bytes, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1552                                tvb, offset, bytes, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1554                 tvb, offset, bytes, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1556                 tvb, offset, bytes, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1558                 tvb, offset, bytes, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1560                 tvb, offset, bytes, mask);
1561         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1562                 tvb, offset, bytes, mask);
1563         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1564                 tvb, offset, bytes, mask);
1565
1566         offset += bytes;
1567
1568         return offset;
1569 }
1570
1571 /* 3.11 */
1572 static int
1573 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1574 {
1575         guint32 mask;
1576         proto_item *item = NULL;
1577         proto_tree *tree = NULL;
1578
1579         mask = tvb_get_letohl(tvb, offset);
1580
1581         if(parent_tree){
1582                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1583                         "File Attributes: 0x%08x", mask);
1584                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1585         }
1586
1587         /*
1588          * XXX - Network Monitor disagrees on some of the
1589          * bits, e.g. the bits above temporary are "atomic write"
1590          * and "transaction write", and it says nothing about the
1591          * bits above that.
1592          *
1593          * Does the Win32 API documentation, or the NT Native API book,
1594          * suggest anything?
1595          */
1596         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1597                 tvb, offset, 4, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1599                 tvb, offset, 4, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1601                 tvb, offset, 4, mask);
1602         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1603                 tvb, offset, 4, mask);
1604         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1605                 tvb, offset, 4, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1607                 tvb, offset, 4, mask);
1608         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1609                 tvb, offset, 4, mask);
1610         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1611                 tvb, offset, 4, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1613                 tvb, offset, 4, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1615                 tvb, offset, 4, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1617                 tvb, offset, 4, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1619                 tvb, offset, 4, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1621                 tvb, offset, 4, mask);
1622         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1623                 tvb, offset, 4, mask);
1624         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1625                 tvb, offset, 4, mask);
1626
1627         offset += 4;
1628
1629         return offset;
1630 }
1631
1632 static int
1633 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1634 {
1635         guint8 mask;
1636         proto_item *item = NULL;
1637         proto_tree *tree = NULL;
1638
1639         mask = tvb_get_guint8(tvb, offset);
1640
1641         if(parent_tree){
1642                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1643                         "File Attributes: 0x%02x", mask);
1644                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1645         }
1646         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1647                 tvb, offset, 1, mask);
1648         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1649                 tvb, offset, 1, mask);
1650         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1651                 tvb, offset, 1, mask);
1652         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1653                 tvb, offset, 1, mask);
1654         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1655                 tvb, offset, 1, mask);
1656         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1657                 tvb, offset, 1, mask);
1658
1659         offset += 1;
1660
1661         return offset;
1662 }
1663
1664 static const true_false_string tfs_search_attribute_read_only = {
1665         "Include READ ONLY files in search results",
1666         "Do NOT include read only files in search results",
1667 };
1668 static const true_false_string tfs_search_attribute_hidden = {
1669         "Include HIDDEN files in search results",
1670         "Do NOT include hidden files in search results"
1671 };
1672 static const true_false_string tfs_search_attribute_system = {
1673         "Include SYSTEM files in search results",
1674         "Do NOT include system files in search results"
1675 };
1676 static const true_false_string tfs_search_attribute_volume = {
1677         "Include VOLUME IDs in search results",
1678         "Do NOT include volume IDs in search results"
1679 };
1680 static const true_false_string tfs_search_attribute_directory = {
1681         "Include DIRECTORIES in search results",
1682         "Do NOT include directories in search results"
1683 };
1684 static const true_false_string tfs_search_attribute_archive = {
1685         "Include ARCHIVE files in search results",
1686         "Do NOT include archive files in search results"
1687 };
1688
1689 static int
1690 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1691 {
1692         guint16 mask;
1693         proto_item *item = NULL;
1694         proto_tree *tree = NULL;
1695
1696         mask = tvb_get_letohs(tvb, offset);
1697
1698         if(parent_tree){
1699                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1700                         "Search Attributes: 0x%04x", mask);
1701                 tree = proto_item_add_subtree(item, ett_smb_search);
1702         }
1703
1704         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1705                 tvb, offset, 2, mask);
1706         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1707                 tvb, offset, 2, mask);
1708         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1709                 tvb, offset, 2, mask);
1710         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1711                 tvb, offset, 2, mask);
1712         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1713                 tvb, offset, 2, mask);
1714         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1715                 tvb, offset, 2, mask);
1716
1717         offset += 2;
1718         return offset;
1719 }
1720
1721 #if 0
1722 /*
1723  * XXX - this isn't used.
1724  * Is this used for anything?  NT Create AndX doesn't use it.
1725  * Is there some 16-bit attribute field with more bits than Read Only,
1726  * Hidden, System, Volume ID, Directory, and Archive?
1727  */
1728 static int
1729 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1730 {
1731         guint32 mask;
1732         proto_item *item = NULL;
1733         proto_tree *tree = NULL;
1734
1735         mask = tvb_get_letohl(tvb, offset);
1736
1737         if(parent_tree){
1738                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1739                         "File Attributes: 0x%08x", mask);
1740                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1741         }
1742         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1743                 tvb, offset, 2, mask);
1744         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1745                 tvb, offset, 2, mask);
1746         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1747                 tvb, offset, 2, mask);
1748         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1749                 tvb, offset, 2, mask);
1750         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1751                 tvb, offset, 2, mask);
1752         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1753                 tvb, offset, 2, mask);
1754         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1755                 tvb, offset, 2, mask);
1756         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1757                 tvb, offset, 2, mask);
1758         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1759                 tvb, offset, 2, mask);
1760         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1761                 tvb, offset, 2, mask);
1762         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1763                 tvb, offset, 2, mask);
1764         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1765                 tvb, offset, 2, mask);
1766         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1767                 tvb, offset, 2, mask);
1768         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1769                 tvb, offset, 2, mask);
1770         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1771                 tvb, offset, 2, mask);
1772
1773         offset += 2;
1774
1775         return offset;
1776 }
1777 #endif
1778
1779
1780 #define SERVER_CAP_RAW_MODE            0x00000001
1781 #define SERVER_CAP_MPX_MODE            0x00000002
1782 #define SERVER_CAP_UNICODE             0x00000004
1783 #define SERVER_CAP_LARGE_FILES         0x00000008
1784 #define SERVER_CAP_NT_SMBS             0x00000010
1785 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1786 #define SERVER_CAP_STATUS32            0x00000040
1787 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1788 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1789 #define SERVER_CAP_NT_FIND             0x00000200
1790 #define SERVER_CAP_DFS                 0x00001000
1791 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1792 #define SERVER_CAP_LARGE_READX         0x00004000
1793 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1794 #define SERVER_CAP_UNIX                0x00800000
1795 #define SERVER_CAP_RESERVED            0x02000000
1796 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1797 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1798 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1799 static const true_false_string tfs_server_cap_raw_mode = {
1800         "Read Raw and Write Raw are supported",
1801         "Read Raw and Write Raw are not supported"
1802 };
1803 static const true_false_string tfs_server_cap_mpx_mode = {
1804         "Read Mpx and Write Mpx are supported",
1805         "Read Mpx and Write Mpx are not supported"
1806 };
1807 static const true_false_string tfs_server_cap_unicode = {
1808         "Unicode strings are supported",
1809         "Unicode strings are not supported"
1810 };
1811 static const true_false_string tfs_server_cap_large_files = {
1812         "Large files are supported",
1813         "Large files are not supported",
1814 };
1815 static const true_false_string tfs_server_cap_nt_smbs = {
1816         "NT SMBs are supported",
1817         "NT SMBs are not supported"
1818 };
1819 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1820         "RPC remote APIs are supported",
1821         "RPC remote APIs are not supported"
1822 };
1823 static const true_false_string tfs_server_cap_nt_status = {
1824         "NT status codes are supported",
1825         "NT status codes are not supported"
1826 };
1827 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1828         "Level 2 oplocks are supported",
1829         "Level 2 oplocks are not supported"
1830 };
1831 static const true_false_string tfs_server_cap_lock_and_read = {
1832         "Lock and Read is supported",
1833         "Lock and Read is not supported"
1834 };
1835 static const true_false_string tfs_server_cap_nt_find = {
1836         "NT Find is supported",
1837         "NT Find is not supported"
1838 };
1839 static const true_false_string tfs_server_cap_dfs = {
1840         "Dfs is supported",
1841         "Dfs is not supported"
1842 };
1843 static const true_false_string tfs_server_cap_infolevel_passthru = {
1844         "NT information level request passthrough is supported",
1845         "NT information level request passthrough is not supported"
1846 };
1847 static const true_false_string tfs_server_cap_large_readx = {
1848         "Large Read andX is supported",
1849         "Large Read andX is not supported"
1850 };
1851 static const true_false_string tfs_server_cap_large_writex = {
1852         "Large Write andX is supported",
1853         "Large Write andX is not supported"
1854 };
1855 static const true_false_string tfs_server_cap_unix = {
1856         "UNIX extensions are supported",
1857         "UNIX extensions are not supported"
1858 };
1859 static const true_false_string tfs_server_cap_reserved = {
1860         "Reserved",
1861         "Reserved"
1862 };
1863 static const true_false_string tfs_server_cap_bulk_transfer = {
1864         "Bulk Read and Bulk Write are supported",
1865         "Bulk Read and Bulk Write are not supported"
1866 };
1867 static const true_false_string tfs_server_cap_compressed_data = {
1868         "Compressed data transfer is supported",
1869         "Compressed data transfer is not supported"
1870 };
1871 static const true_false_string tfs_server_cap_extended_security = {
1872         "Extended security exchanges are supported",
1873         "Extended security exchanges are not supported"
1874 };
1875 static int
1876 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1877 {
1878         guint32 mask;
1879         proto_item *item = NULL;
1880         proto_tree *tree = NULL;
1881
1882         mask = tvb_get_letohl(tvb, offset);
1883
1884         if(parent_tree){
1885                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1886                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1887         }
1888
1889         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1890                 tvb, offset, 4, mask);
1891         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1892                 tvb, offset, 4, mask);
1893         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1894                 tvb, offset, 4, mask);
1895         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1896                 tvb, offset, 4, mask);
1897         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1898                 tvb, offset, 4, mask);
1899         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1900                 tvb, offset, 4, mask);
1901         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1902                 tvb, offset, 4, mask);
1903         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1904                 tvb, offset, 4, mask);
1905         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1906                 tvb, offset, 4, mask);
1907         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1908                 tvb, offset, 4, mask);
1909         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1910                 tvb, offset, 4, mask);
1911         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1912                 tvb, offset, 4, mask);
1913         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1914                 tvb, offset, 4, mask);
1915         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1916                 tvb, offset, 4, mask);
1917         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1918                 tvb, offset, 4, mask);
1919         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1920                 tvb, offset, 4, mask);
1921         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1922                 tvb, offset, 4, mask);
1923         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1924                 tvb, offset, 4, mask);
1925         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1926                 tvb, offset, 4, mask);
1927
1928         return mask;
1929 }
1930
1931 #define RAWMODE_READ   0x01
1932 #define RAWMODE_WRITE  0x02
1933 static const true_false_string tfs_rm_read = {
1934         "Read Raw is supported",
1935         "Read Raw is not supported"
1936 };
1937 static const true_false_string tfs_rm_write = {
1938         "Write Raw is supported",
1939         "Write Raw is not supported"
1940 };
1941
1942 static int
1943 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1944 {
1945         guint16 mask;
1946         proto_item *item = NULL;
1947         proto_tree *tree = NULL;
1948
1949         mask = tvb_get_letohs(tvb, offset);
1950
1951         if(parent_tree){
1952                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1953                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1954         }
1955
1956         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1957         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1958
1959         offset += 2;
1960
1961         return offset;
1962 }
1963
1964 #define SECURITY_MODE_MODE             0x01
1965 #define SECURITY_MODE_PASSWORD         0x02
1966 #define SECURITY_MODE_SIGNATURES       0x04
1967 #define SECURITY_MODE_SIG_REQUIRED     0x08
1968 static const true_false_string tfs_sm_mode = {
1969         "USER security mode",
1970         "SHARE security mode"
1971 };
1972 static const true_false_string tfs_sm_password = {
1973         "ENCRYPTED password. Use challenge/response",
1974         "PLAINTEXT password"
1975 };
1976 static const true_false_string tfs_sm_signatures = {
1977         "Security signatures ENABLED",
1978         "Security signatures NOT enabled"
1979 };
1980 static const true_false_string tfs_sm_sig_required = {
1981         "Security signatures REQUIRED",
1982         "Security signatures NOT required"
1983 };
1984
1985 static int
1986 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1987 {
1988         guint16 mask = 0;
1989         proto_item *item = NULL;
1990         proto_tree *tree = NULL;
1991
1992         switch(wc){
1993         case 13:
1994                 mask = tvb_get_letohs(tvb, offset);
1995                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1996                                 "Security Mode: 0x%04x", mask);
1997                 tree = proto_item_add_subtree(item, ett_smb_mode);
1998                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1999                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2000                 offset += 2;
2001                 break;
2002
2003         case 17:
2004                 mask = tvb_get_guint8(tvb, offset);
2005                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2006                                 "Security Mode: 0x%02x", mask);
2007                 tree = proto_item_add_subtree(item, ett_smb_mode);
2008                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2009                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2010                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2011                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2012                 offset += 1;
2013                 break;
2014         }
2015
2016         return offset;
2017 }
2018
2019 static int
2020 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2021 {
2022         proto_item *it = NULL;
2023         proto_tree *tr = NULL;
2024         guint16 bc;
2025         guint8 wc;
2026
2027         WORD_COUNT;
2028
2029         BYTE_COUNT;
2030
2031         if(tree){
2032                 it = proto_tree_add_text(tree, tvb, offset, bc,
2033                                 "Requested Dialects");
2034                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2035         }
2036
2037         while(bc){
2038                 int len;
2039                 const guint8 *str;
2040                 proto_item *dit = NULL;
2041                 proto_tree *dtr = NULL;
2042
2043                 /* XXX - what if this runs past bc? */
2044                 len = tvb_strsize(tvb, offset+1);
2045                 str = tvb_get_ptr(tvb, offset+1, len);
2046
2047                 if(tr){
2048                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2049                                         "Dialect: %s", str);
2050                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2051                 }
2052
2053                 /* Buffer Format */
2054                 CHECK_BYTE_COUNT(1);
2055                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2056                         TRUE);
2057                 COUNT_BYTES(1);
2058
2059                 /*Dialect Name */
2060                 CHECK_BYTE_COUNT(len);
2061                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2062                         len, str);
2063                 COUNT_BYTES(len);
2064         }
2065
2066         END_OF_SMB
2067
2068         return offset;
2069 }
2070
2071 static int
2072 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2073 {
2074         smb_info_t *si = pinfo->private_data;
2075         guint8 wc;
2076         guint16 dialect;
2077         const char *dn;
2078         int dn_len;
2079         guint16 bc;
2080         guint16 ekl=0;
2081         guint32 caps=0;
2082         gint16 tz;
2083
2084         WORD_COUNT;
2085
2086         /* Dialect Index */
2087         dialect = tvb_get_letohs(tvb, offset);
2088         switch(wc){
2089         case 1:
2090                 if(dialect==0xffff){
2091                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2092                                 tvb, offset, 2, dialect,
2093                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2094                 } else {
2095                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2096                                 tvb, offset, 2, dialect);
2097                 }
2098                 break;
2099         case 13:
2100                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2101                         tvb, offset, 2, dialect,
2102                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2103                 break;
2104         case 17:
2105                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2106                         tvb, offset, 2, dialect,
2107                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2108                 break;
2109         default:
2110                 proto_tree_add_text(tree, tvb, offset, wc*2,
2111                         "Words for unknown response format");
2112                 offset += wc*2;
2113                 goto bytecount;
2114         }
2115         offset += 2;
2116
2117         switch(wc){
2118         case 13:
2119                 /* Security Mode */
2120                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2121
2122                 /* Maximum Transmit Buffer Size */
2123                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2124                         tvb, offset, 2, TRUE);
2125                 offset += 2;
2126
2127                 /* Maximum Multiplex Count */
2128                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2129                         tvb, offset, 2, TRUE);
2130                 offset += 2;
2131
2132                 /* Maximum Vcs Number */
2133                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2134                         tvb, offset, 2, TRUE);
2135                 offset += 2;
2136
2137                 /* raw mode */
2138                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2139
2140                 /* session key */
2141                 proto_tree_add_item(tree, hf_smb_session_key,
2142                         tvb, offset, 4, TRUE);
2143                 offset += 4;
2144
2145                 /* current time and date at server */
2146                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2147                     TRUE);
2148
2149                 /* time zone */
2150                 tz = tvb_get_letohs(tvb, offset);
2151                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2152                 offset += 2;
2153
2154                 /* encryption key length */
2155                 ekl = tvb_get_letohs(tvb, offset);
2156                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2157                 offset += 2;
2158
2159                 /* 2 reserved bytes */
2160                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2161                 offset += 2;
2162
2163                 break;
2164
2165         case 17:
2166                 /* Security Mode */
2167                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2168
2169                 /* Maximum Multiplex Count */
2170                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2171                         tvb, offset, 2, TRUE);
2172                 offset += 2;
2173
2174                 /* Maximum Vcs Number */
2175                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2176                         tvb, offset, 2, TRUE);
2177                 offset += 2;
2178
2179                 /* Maximum Transmit Buffer Size */
2180                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2181                         tvb, offset, 4, TRUE);
2182                 offset += 4;
2183
2184                 /* maximum raw buffer size */
2185                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2186                         tvb, offset, 4, TRUE);
2187                 offset += 4;
2188
2189                 /* session key */
2190                 proto_tree_add_item(tree, hf_smb_session_key,
2191                         tvb, offset, 4, TRUE);
2192                 offset += 4;
2193
2194                 /* server capabilities */
2195                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2196                 offset += 4;
2197
2198                 /* system time */
2199                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2200                                 hf_smb_system_time);
2201
2202                 /* time zone */
2203                 tz = tvb_get_letohs(tvb, offset);
2204                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2205                         tvb, offset, 2, tz,
2206                         "Server Time Zone: %d min from UTC", tz);
2207                 offset += 2;
2208
2209                 /* encryption key length */
2210                 ekl = tvb_get_guint8(tvb, offset);
2211                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2212                         tvb, offset, 1, ekl);
2213                 offset += 1;
2214
2215                 break;
2216         }
2217
2218         BYTE_COUNT;
2219
2220         switch(wc){
2221         case 13:
2222                 /* challenge/response encryption key */
2223                 if(ekl){
2224                         CHECK_BYTE_COUNT(ekl);
2225                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2226                         COUNT_BYTES(ekl);
2227                 }
2228
2229                 /*
2230                  * Primary domain.
2231                  *
2232                  * XXX - not present if negotiated dialect isn't
2233                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2234                  * have to see the request, or assume what dialect strings
2235                  * were sent, to determine that.
2236                  *
2237                  * Is this something other than a primary domain if the
2238                  * negotiated dialect is Windows for Workgroups 3.1a?
2239                  * It appears to be 8 bytes of binary data in at least
2240                  * one capture - is that an encryption key or something
2241                  * such as that?
2242                  */
2243                 dn = get_unicode_or_ascii_string(tvb, &offset,
2244                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2245                 if (dn == NULL)
2246                         goto endofcommand;
2247                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2248                         offset, dn_len,dn);
2249                 COUNT_BYTES(dn_len);
2250                 break;
2251
2252         case 17:
2253                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2254                         /* challenge/response encryption key */
2255                         /* XXX - is this aligned on an even boundary? */
2256                         if(ekl){
2257                                 CHECK_BYTE_COUNT(ekl);
2258                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2259                                         tvb, offset, ekl, TRUE);
2260                                 COUNT_BYTES(ekl);
2261                         }
2262
2263                         /* domain */
2264                         /* this string is special, unicode is flagged in caps */
2265                         /* This string is NOT padded to be 16bit aligned.
2266                            (seen in actual capture)
2267                            XXX - I've seen a capture where it appears to be
2268                            so aligned, but I've also seen captures where
2269                            it is.  The captures where it appeared to be
2270                            aligned may have been from buggy servers. */
2271                         /* However, don't get rid of existing setting */
2272                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2273                           si->unicode;
2274
2275                         dn = get_unicode_or_ascii_string(tvb,
2276                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2277                                 &bc);
2278                         if (dn == NULL)
2279                                 goto endofcommand;
2280                         proto_tree_add_string(tree, hf_smb_primary_domain,
2281                                 tvb, offset, dn_len, dn);
2282                         COUNT_BYTES(dn_len);
2283
2284                         /* server name, seen in w2k pro capture */
2285                         dn = get_unicode_or_ascii_string(tvb,
2286                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2287                                 &bc);
2288                         if (dn == NULL)
2289                                 goto endofcommand;
2290                         proto_tree_add_string(tree, hf_smb_server,
2291                                 tvb, offset, dn_len, dn);
2292                         COUNT_BYTES(dn_len);
2293
2294                 } else {
2295                         proto_item *blob_item;
2296
2297                         /* guid */
2298                         /* XXX - show it in the standard Microsoft format
2299                            for GUIDs? */
2300                         CHECK_BYTE_COUNT(16);
2301                         proto_tree_add_item(tree, hf_smb_server_guid,
2302                                 tvb, offset, 16, TRUE);
2303                         COUNT_BYTES(16);
2304
2305                         blob_item = proto_tree_add_item(
2306                                 tree, hf_smb_security_blob,
2307                                 tvb, offset, bc, TRUE);
2308
2309                         /* security blob */
2310                         /* 
2311                          * If Extended security and BCC == 16, then raw 
2312                          * NTLMSSP is in use. We need to save this info
2313                          */
2314  
2315                         if(bc){
2316                                 tvbuff_t *gssapi_tvb;
2317                                 proto_tree *gssapi_tree;
2318
2319                                 gssapi_tree = proto_item_add_subtree(
2320                                         blob_item, ett_smb_secblob);
2321
2322                                 gssapi_tvb = tvb_new_subset(
2323                                         tvb, offset, bc, bc);
2324
2325                                 call_dissector(
2326                                         gssapi_handle, gssapi_tvb, pinfo,
2327                                         gssapi_tree);
2328
2329                                 if (si->ct)
2330                                   si->ct->raw_ntlmssp = 0;
2331
2332                                 COUNT_BYTES(bc);
2333                         }
2334                         else { 
2335
2336                           /*
2337                            * There is no blob. We just have to make sure
2338                            * that subsequent routines know to call the 
2339                            * right things ...
2340                            */
2341
2342                           if (si->ct)
2343                             si->ct->raw_ntlmssp = 1;
2344
2345                         }
2346                 }
2347                 break;
2348         }
2349
2350         END_OF_SMB
2351
2352         return offset;
2353 }
2354
2355
2356 static int
2357 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2358 {
2359         smb_info_t *si = pinfo->private_data;
2360         int dn_len;
2361         const char *dn;
2362         guint8 wc;
2363         guint16 bc;
2364
2365         WORD_COUNT;
2366
2367         BYTE_COUNT;
2368
2369         /* buffer format */
2370         CHECK_BYTE_COUNT(1);
2371         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2372         COUNT_BYTES(1);
2373
2374         /* dir name */
2375         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2376                 FALSE, FALSE, &bc);
2377         if (dn == NULL)
2378                 goto endofcommand;
2379         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2380                 dn);
2381         COUNT_BYTES(dn_len);
2382
2383         if (check_col(pinfo->cinfo, COL_INFO)) {
2384                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2385         }
2386
2387         END_OF_SMB
2388
2389         return offset;
2390 }
2391
2392 static int
2393 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2394 {
2395         guint8 wc;
2396         guint16 bc;
2397
2398         WORD_COUNT;
2399
2400         BYTE_COUNT;
2401
2402         END_OF_SMB
2403
2404         return offset;
2405 }
2406
2407 static int
2408 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2409 {
2410         guint16 ec, bc;
2411         guint8 wc;
2412
2413         WORD_COUNT;
2414
2415         /* echo count */
2416         ec = tvb_get_letohs(tvb, offset);
2417         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2418         offset += 2;
2419
2420         BYTE_COUNT;
2421
2422         if (bc != 0) {
2423                 /* echo data */
2424                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2425                 COUNT_BYTES(bc);
2426         }
2427
2428         END_OF_SMB
2429
2430         return offset;
2431 }
2432
2433 static int
2434 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2435 {
2436         guint16 bc;
2437         guint8 wc;
2438
2439         WORD_COUNT;
2440
2441         /* echo sequence number */
2442         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2443         offset += 2;
2444
2445         BYTE_COUNT;
2446
2447         if (bc != 0) {
2448                 /* echo data */
2449                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2450                 COUNT_BYTES(bc);
2451         }
2452
2453         END_OF_SMB
2454
2455         return offset;
2456 }
2457
2458 static int
2459 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2460 {
2461         smb_info_t *si = pinfo->private_data;
2462         int an_len, pwlen;
2463         const char *an;
2464         guint8 wc;
2465         guint16 bc;
2466
2467         WORD_COUNT;
2468
2469         BYTE_COUNT;
2470
2471         /* buffer format */
2472         CHECK_BYTE_COUNT(1);
2473         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2474         COUNT_BYTES(1);
2475
2476         /* Path */
2477         an = get_unicode_or_ascii_string(tvb, &offset,
2478                 si->unicode, &an_len, FALSE, FALSE, &bc);
2479         if (an == NULL)
2480                 goto endofcommand;
2481         proto_tree_add_string(tree, hf_smb_path, tvb,
2482                 offset, an_len, an);
2483         COUNT_BYTES(an_len);
2484
2485         if (check_col(pinfo->cinfo, COL_INFO)) {
2486                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2487         }
2488
2489         /* buffer format */
2490         CHECK_BYTE_COUNT(1);
2491         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2492         COUNT_BYTES(1);
2493
2494         /* password, ANSI */
2495         /* XXX - what if this runs past bc? */
2496         pwlen = tvb_strsize(tvb, offset);
2497         CHECK_BYTE_COUNT(pwlen);
2498         proto_tree_add_item(tree, hf_smb_password,
2499                 tvb, offset, pwlen, TRUE);
2500         COUNT_BYTES(pwlen);
2501
2502         /* buffer format */
2503         CHECK_BYTE_COUNT(1);
2504         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2505         COUNT_BYTES(1);
2506
2507         /* Service */
2508         an = get_unicode_or_ascii_string(tvb, &offset,
2509                 si->unicode, &an_len, FALSE, FALSE, &bc);
2510         if (an == NULL)
2511                 goto endofcommand;
2512         proto_tree_add_string(tree, hf_smb_service, tvb,
2513                 offset, an_len, an);
2514         COUNT_BYTES(an_len);
2515
2516         END_OF_SMB
2517
2518         return offset;
2519 }
2520
2521 static int
2522 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2523 {
2524         guint8 wc;
2525         guint16 bc;
2526
2527         WORD_COUNT;
2528
2529         /* Maximum Buffer Size */
2530         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2531         offset += 2;
2532
2533         /* tid */
2534         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2535         offset += 2;
2536
2537         BYTE_COUNT;
2538
2539         END_OF_SMB
2540
2541         return offset;
2542 }
2543
2544
2545 static const true_false_string tfs_of_create = {
2546         "Create file if it does not exist",
2547         "Fail if file does not exist"
2548 };
2549 static const value_string of_open[] = {
2550         { 0,            "Fail if file exists"},
2551         { 1,            "Open file if it exists"},
2552         { 2,            "Truncate file if it exists"},
2553         {0, NULL}
2554 };
2555 static int
2556 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2557 {
2558         guint16 mask;
2559         proto_item *item = NULL;
2560         proto_tree *tree = NULL;
2561
2562         mask = tvb_get_letohs(tvb, offset);
2563
2564         if(parent_tree){
2565                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2566                         "Open Function: 0x%04x", mask);
2567                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2568         }
2569
2570         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2571                 tvb, offset, 2, mask);
2572         proto_tree_add_uint(tree, hf_smb_open_function_open,
2573                 tvb, offset, 2, mask);
2574
2575         offset += 2;
2576
2577         return offset;
2578 }
2579
2580
2581 static const true_false_string tfs_mf_file = {
2582         "Target must be a file",
2583         "Target needn't be a file"
2584 };
2585 static const true_false_string tfs_mf_dir = {
2586         "Target must be a directory",
2587         "Target needn't be a directory"
2588 };
2589 static const true_false_string tfs_mf_verify = {
2590         "MUST verify all writes",
2591         "Don't have to verify writes"
2592 };
2593 static int
2594 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2595 {
2596         guint16 mask;
2597         proto_item *item = NULL;
2598         proto_tree *tree = NULL;
2599
2600         mask = tvb_get_letohs(tvb, offset);
2601
2602         if(parent_tree){
2603                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2604                         "Flags: 0x%04x", mask);
2605                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2606         }
2607
2608         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2609                 tvb, offset, 2, mask);
2610         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2611                 tvb, offset, 2, mask);
2612         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2613                 tvb, offset, 2, mask);
2614
2615         offset += 2;
2616
2617         return offset;
2618 }
2619
2620 static const true_false_string tfs_cf_mode = {
2621         "ASCII",
2622         "Binary"
2623 };
2624 static const true_false_string tfs_cf_tree_copy = {
2625         "Copy is a tree copy",
2626         "Copy is a file copy"
2627 };
2628 static const true_false_string tfs_cf_ea_action = {
2629         "Fail copy",
2630         "Discard EAs"
2631 };
2632 static int
2633 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2634 {
2635         guint16 mask;
2636         proto_item *item = NULL;
2637         proto_tree *tree = NULL;
2638
2639         mask = tvb_get_letohs(tvb, offset);
2640
2641         if(parent_tree){
2642                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2643                         "Flags: 0x%04x", mask);
2644                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2645         }
2646
2647         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2648                 tvb, offset, 2, mask);
2649         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2650                 tvb, offset, 2, mask);
2651         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2652                 tvb, offset, 2, mask);
2653         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2654                 tvb, offset, 2, mask);
2655         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2656                 tvb, offset, 2, mask);
2657         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2658                 tvb, offset, 2, mask);
2659         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2660                 tvb, offset, 2, mask);
2661
2662         offset += 2;
2663
2664         return offset;
2665 }
2666
2667 static int
2668 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2669 {
2670         smb_info_t *si = pinfo->private_data;
2671         int fn_len;
2672         guint16 tid;
2673         guint16 bc;
2674         guint8 wc;
2675         const char *fn;
2676
2677         WORD_COUNT;
2678
2679         /* tid */
2680         tid = tvb_get_letohs(tvb, offset);
2681         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2682                 "TID (target): 0x%04x", tid);
2683         offset += 2;
2684
2685         /* open function */
2686         offset = dissect_open_function(tvb, tree, offset);
2687
2688         /* move flags */
2689         offset = dissect_move_flags(tvb, tree, offset);
2690
2691         BYTE_COUNT;
2692
2693         /* buffer format */
2694         CHECK_BYTE_COUNT(1);
2695         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2696         COUNT_BYTES(1);
2697
2698         /* file name */
2699         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2700                 FALSE, FALSE, &bc);
2701         if (fn == NULL)
2702                 goto endofcommand;
2703         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2704                 fn_len, fn, "Old File Name: %s", fn);
2705         COUNT_BYTES(fn_len);
2706
2707         if (check_col(pinfo->cinfo, COL_INFO)) {
2708                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2709         }
2710
2711         /* buffer format */
2712         CHECK_BYTE_COUNT(1);
2713         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2714         COUNT_BYTES(1);
2715
2716         /* file name */
2717         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2718                 FALSE, FALSE, &bc);
2719         if (fn == NULL)
2720                 goto endofcommand;
2721         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2722                 fn_len, fn, "New File Name: %s", fn);
2723         COUNT_BYTES(fn_len);
2724
2725         if (check_col(pinfo->cinfo, COL_INFO)) {
2726                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2727         }
2728
2729         END_OF_SMB
2730
2731         return offset;
2732 }
2733
2734 static int
2735 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2736 {
2737         smb_info_t *si = pinfo->private_data;
2738         int fn_len;
2739         guint16 tid;
2740         guint16 bc;
2741         guint8 wc;
2742         const char *fn;
2743
2744         WORD_COUNT;
2745
2746         /* tid */
2747         tid = tvb_get_letohs(tvb, offset);
2748         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2749                 "TID (target): 0x%04x", tid);
2750         offset += 2;
2751
2752         /* open function */
2753         offset = dissect_open_function(tvb, tree, offset);
2754
2755         /* copy flags */
2756         offset = dissect_copy_flags(tvb, tree, offset);
2757
2758         BYTE_COUNT;
2759
2760         /* buffer format */
2761         CHECK_BYTE_COUNT(1);
2762         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2763         COUNT_BYTES(1);
2764
2765         /* file name */
2766         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2767                 FALSE, FALSE, &bc);
2768         if (fn == NULL)
2769                 goto endofcommand;
2770         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2771                 fn_len, fn, "Source File Name: %s", fn);
2772         COUNT_BYTES(fn_len);
2773
2774         if (check_col(pinfo->cinfo, COL_INFO)) {
2775                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2776         }
2777
2778         /* buffer format */
2779         CHECK_BYTE_COUNT(1);
2780         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2781         COUNT_BYTES(1);
2782
2783         /* file name */
2784         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2785                 FALSE, FALSE, &bc);
2786         if (fn == NULL)
2787                 goto endofcommand;
2788         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2789                 fn_len, fn, "Destination File Name: %s", fn);
2790         COUNT_BYTES(fn_len);
2791
2792         if (check_col(pinfo->cinfo, COL_INFO)) {
2793                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2794         }
2795
2796         END_OF_SMB
2797
2798         return offset;
2799 }
2800
2801 static int
2802 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2803 {
2804         smb_info_t *si = pinfo->private_data;
2805         int fn_len;
2806         const char *fn;
2807         guint8 wc;
2808         guint16 bc;
2809
2810         WORD_COUNT;
2811
2812         /* # of files moved */
2813         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2814         offset += 2;
2815
2816         BYTE_COUNT;
2817
2818         /* buffer format */
2819         CHECK_BYTE_COUNT(1);
2820         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2821         COUNT_BYTES(1);
2822
2823         /* file name */
2824         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2825                 FALSE, FALSE, &bc);
2826         if (fn == NULL)
2827                 goto endofcommand;
2828         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2829                 fn);
2830         COUNT_BYTES(fn_len);
2831
2832         END_OF_SMB
2833
2834         return offset;
2835 }
2836
2837 static int
2838 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2839 {
2840         smb_info_t *si = pinfo->private_data;
2841         int fn_len;
2842         const char *fn;
2843         guint8 wc;
2844         guint16 bc;
2845
2846         WORD_COUNT;
2847
2848         /* desired access */
2849         offset = dissect_access(tvb, tree, offset, "Desired");
2850
2851         /* Search Attributes */
2852         offset = dissect_search_attributes(tvb, tree, offset);
2853
2854         BYTE_COUNT;
2855
2856         /* buffer format */
2857         CHECK_BYTE_COUNT(1);
2858         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2859         COUNT_BYTES(1);
2860
2861         /* file name */
2862         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2863                 FALSE, FALSE, &bc);
2864         if (fn == NULL)
2865                 goto endofcommand;
2866         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2867                 fn);
2868         COUNT_BYTES(fn_len);
2869
2870         if (check_col(pinfo->cinfo, COL_INFO)) {
2871                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2872         }
2873
2874         END_OF_SMB
2875
2876         return offset;
2877 }
2878
2879 void
2880 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2881     int len, guint16 fid)
2882 {
2883         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2884         if (check_col(pinfo->cinfo, COL_INFO))
2885                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2886 }
2887
2888 static int
2889 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2890 {
2891         guint8 wc;
2892         guint16 bc;
2893         guint16 fid;
2894
2895         WORD_COUNT;
2896
2897         /* fid */
2898         fid = tvb_get_letohs(tvb, offset);
2899         add_fid(tvb, pinfo, tree, offset, 2, fid);
2900         offset += 2;
2901
2902         /* File Attributes */
2903         offset = dissect_file_attributes(tvb, tree, offset, 2);
2904
2905         /* last write time */
2906         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2907
2908         /* File Size */
2909         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2910         offset += 4;
2911
2912         /* granted access */
2913         offset = dissect_access(tvb, tree, offset, "Granted");
2914
2915         BYTE_COUNT;
2916
2917         END_OF_SMB
2918
2919         return offset;
2920 }
2921
2922 static int
2923 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2924 {
2925         guint8 wc;
2926         guint16 bc;
2927         guint16 fid;
2928
2929         WORD_COUNT;
2930
2931         /* fid */
2932         fid = tvb_get_letohs(tvb, offset);
2933         add_fid(tvb, pinfo, tree, offset, 2, fid);
2934         offset += 2;
2935
2936         BYTE_COUNT;
2937
2938         END_OF_SMB
2939
2940         return offset;
2941 }
2942
2943 static int
2944 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2945 {
2946         smb_info_t *si = pinfo->private_data;
2947         int fn_len;
2948         const char *fn;
2949         guint8 wc;
2950         guint16 bc;
2951
2952         WORD_COUNT;
2953
2954         /* file attributes */
2955         offset = dissect_file_attributes(tvb, tree, offset, 2);
2956
2957         /* creation time */
2958         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2959
2960         BYTE_COUNT;
2961
2962         /* buffer format */
2963         CHECK_BYTE_COUNT(1);
2964         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2965         COUNT_BYTES(1);
2966
2967         /* File Name */
2968         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2969                 FALSE, FALSE, &bc);
2970         if (fn == NULL)
2971                 goto endofcommand;
2972         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2973                 fn);
2974         COUNT_BYTES(fn_len);
2975
2976         if (check_col(pinfo->cinfo, COL_INFO)) {
2977                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2978         }
2979
2980         END_OF_SMB
2981
2982         return offset;
2983 }
2984
2985 static int
2986 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2987 {
2988         guint8 wc;
2989         guint16 bc, fid;
2990
2991         WORD_COUNT;
2992
2993         /* fid */
2994         fid = tvb_get_letohs(tvb, offset);
2995         add_fid(tvb, pinfo, tree, offset, 2, fid);
2996         offset += 2;
2997
2998         /* last write time */
2999         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3000
3001         BYTE_COUNT;
3002
3003         END_OF_SMB
3004
3005         return offset;
3006 }
3007
3008 static int
3009 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3010 {
3011         smb_info_t *si = pinfo->private_data;
3012         int fn_len;
3013         const char *fn;
3014         guint8 wc;
3015         guint16 bc;
3016
3017         WORD_COUNT;
3018
3019         /* search attributes */
3020         offset = dissect_search_attributes(tvb, tree, offset);
3021
3022         BYTE_COUNT;
3023
3024         /* buffer format */
3025         CHECK_BYTE_COUNT(1);
3026         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3027         COUNT_BYTES(1);
3028
3029         /* file name */
3030         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3031                 FALSE, FALSE, &bc);
3032         if (fn == NULL)
3033                 goto endofcommand;
3034         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3035                 fn);
3036         COUNT_BYTES(fn_len);
3037
3038         if (check_col(pinfo->cinfo, COL_INFO)) {
3039                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3040         }
3041
3042         END_OF_SMB
3043
3044         return offset;
3045 }
3046
3047 static int
3048 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3049 {
3050         smb_info_t *si = pinfo->private_data;
3051         int fn_len;
3052         const char *fn;
3053         guint8 wc;
3054         guint16 bc;
3055
3056         WORD_COUNT;
3057
3058         /* search attributes */
3059         offset = dissect_search_attributes(tvb, tree, offset);
3060
3061         BYTE_COUNT;
3062
3063         /* buffer format */
3064         CHECK_BYTE_COUNT(1);
3065         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3066         COUNT_BYTES(1);
3067
3068         /* old file name */
3069         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3070                 FALSE, FALSE, &bc);
3071         if (fn == NULL)
3072                 goto endofcommand;
3073         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3074                 fn);
3075         COUNT_BYTES(fn_len);
3076
3077         if (check_col(pinfo->cinfo, COL_INFO)) {
3078                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3079         }
3080
3081         /* buffer format */
3082         CHECK_BYTE_COUNT(1);
3083         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3084         COUNT_BYTES(1);
3085
3086         /* file name */
3087         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3088                 FALSE, FALSE, &bc);
3089         if (fn == NULL)
3090                 goto endofcommand;
3091         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3092                 fn);
3093         COUNT_BYTES(fn_len);
3094
3095         if (check_col(pinfo->cinfo, COL_INFO)) {
3096                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3097         }
3098
3099         END_OF_SMB
3100
3101         return offset;
3102 }
3103
3104 static int
3105 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3106 {
3107         smb_info_t *si = pinfo->private_data;
3108         int fn_len;
3109         const char *fn;
3110         guint8 wc;
3111         guint16 bc;
3112
3113         WORD_COUNT;
3114
3115         /* search attributes */
3116         offset = dissect_search_attributes(tvb, tree, offset);
3117
3118         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3119         offset += 2;
3120
3121         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3122         offset += 4;
3123
3124         BYTE_COUNT;
3125
3126         /* buffer format */
3127         CHECK_BYTE_COUNT(1);
3128         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3129         COUNT_BYTES(1);
3130
3131         /* old file name */
3132         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3133                 FALSE, FALSE, &bc);
3134         if (fn == NULL)
3135                 goto endofcommand;
3136         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3137                 fn);
3138         COUNT_BYTES(fn_len);
3139
3140         if (check_col(pinfo->cinfo, COL_INFO)) {
3141                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3142         }
3143
3144         /* buffer format */
3145         CHECK_BYTE_COUNT(1);
3146         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3147         COUNT_BYTES(1);
3148
3149         /* file name */
3150         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3151                 FALSE, FALSE, &bc);
3152         if (fn == NULL)
3153                 goto endofcommand;
3154         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3155                 fn);
3156         COUNT_BYTES(fn_len);
3157
3158         if (check_col(pinfo->cinfo, COL_INFO)) {
3159                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3160         }
3161
3162         END_OF_SMB
3163
3164         return offset;
3165 }
3166
3167
3168 static int
3169 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3170 {
3171         smb_info_t *si = pinfo->private_data;
3172         guint16 bc;
3173         guint8 wc;
3174         const char *fn;
3175         int fn_len;
3176
3177         WORD_COUNT;
3178
3179         BYTE_COUNT;
3180
3181         /* Buffer Format */
3182         CHECK_BYTE_COUNT(1);
3183         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3184         COUNT_BYTES(1);
3185
3186         /* File Name */
3187         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3188                 FALSE, FALSE, &bc);
3189         if (fn == NULL)
3190                 goto endofcommand;
3191         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3192                 fn);
3193         COUNT_BYTES(fn_len);
3194
3195         if (check_col(pinfo->cinfo, COL_INFO)) {
3196                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3197         }
3198
3199         END_OF_SMB
3200
3201         return offset;
3202 }
3203
3204 static int
3205 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3206 {
3207         guint16 bc;
3208         guint8 wc;
3209
3210         WORD_COUNT;
3211
3212         /* File Attributes */
3213         offset = dissect_file_attributes(tvb, tree, offset, 2);
3214
3215         /* Last Write Time */
3216         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3217
3218         /* File Size */
3219         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3220         offset += 4;
3221
3222         /* 10 reserved bytes */
3223         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3224         offset += 10;
3225
3226         BYTE_COUNT;
3227
3228         END_OF_SMB
3229
3230         return offset;
3231 }
3232
3233 static int
3234 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3235 {
3236         smb_info_t *si = pinfo->private_data;
3237         int fn_len;
3238         const char *fn;
3239         guint8 wc;
3240         guint16 bc;
3241
3242         WORD_COUNT;
3243
3244         /* file attributes */
3245         offset = dissect_file_attributes(tvb, tree, offset, 2);
3246
3247         /* last write time */
3248         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3249
3250         /* 10 reserved bytes */
3251         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3252         offset += 10;
3253
3254         BYTE_COUNT;
3255
3256         /* buffer format */
3257         CHECK_BYTE_COUNT(1);
3258         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3259         COUNT_BYTES(1);
3260
3261         /* file name */
3262         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3263                 FALSE, FALSE, &bc);
3264         if (fn == NULL)
3265                 goto endofcommand;
3266         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3267                 fn);
3268         COUNT_BYTES(fn_len);
3269
3270         if (check_col(pinfo->cinfo, COL_INFO)) {
3271                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3272         }
3273
3274         END_OF_SMB
3275
3276         return offset;
3277 }
3278
3279 static int
3280 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3281 {
3282         guint8 wc;
3283         guint16 cnt=0, bc;
3284         guint32 ofs=0;
3285         smb_info_t *si;
3286         unsigned int fid;
3287
3288         WORD_COUNT;
3289
3290         /* fid */
3291         fid = tvb_get_letohs(tvb, offset);
3292         add_fid(tvb, pinfo, tree, offset, 2, fid);
3293         offset += 2;
3294         if (!pinfo->fd->flags.visited) {
3295                 /* remember the FID for the processing of the response */
3296                 si = (smb_info_t *)pinfo->private_data;
3297                 si->sip->extra_info=(void *)fid;
3298         }
3299
3300         /* read count */
3301         cnt = tvb_get_letohs(tvb, offset);
3302         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3303         offset += 2;
3304
3305         /* offset */
3306         ofs = tvb_get_letohl(tvb, offset);
3307         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3308         offset += 4;
3309
3310         if (check_col(pinfo->cinfo, COL_INFO))
3311                 col_append_fstr(pinfo->cinfo, COL_INFO,
3312                                 ", %u byte%s at offset %u", cnt,
3313                                 (cnt == 1) ? "" : "s", ofs);
3314
3315         /* remaining */
3316         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3317         offset += 2;
3318
3319         BYTE_COUNT;
3320
3321         END_OF_SMB
3322
3323         return offset;
3324 }
3325
3326 int
3327 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3328 {
3329         int tvblen;
3330
3331         if(bc>datalen){
3332                 /* We have some initial padding bytes. */
3333                 /* XXX - use the data offset here instead? */
3334                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3335                         TRUE);
3336                 offset += bc-datalen;
3337                 bc = datalen;
3338         }
3339         tvblen = tvb_length_remaining(tvb, offset);
3340         if(bc>tvblen){
3341                 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);
3342                 offset += tvblen;
3343         } else {
3344                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3345                 offset += bc;
3346         }
3347         return offset;
3348 }
3349
3350 static int
3351 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3352     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3353 {
3354         int tvblen;
3355         tvbuff_t *dcerpc_tvb;
3356
3357         if(bc>datalen){
3358                 /* We have some initial padding bytes. */
3359                 /* XXX - use the data offset here instead? */
3360                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3361                         TRUE);
3362                 offset += bc-datalen;
3363                 bc = datalen;
3364         }
3365         tvblen = tvb_length_remaining(tvb, offset);
3366         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3367         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3368         if(bc>tvblen)
3369                 offset += tvblen;
3370         else
3371                 offset += bc;
3372         return offset;
3373 }
3374
3375 /*
3376  * transporting DCERPC over SMB seems to be implemented in various
3377  * ways. We might just assume it can be done by an almost random
3378  * mix of Trans/Read/Write calls
3379  *
3380  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3381  * and let him sort them out
3382  */
3383 static int
3384 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3385     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3386     guint16 datalen, guint32 ofs, guint16 fid)
3387 {
3388         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3389
3390         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3391                 /* dcerpc call */
3392                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3393                     top_tree, offset, bc, datalen, fid);
3394         } else {
3395                 /* ordinary file data */
3396                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3397         }
3398 }
3399
3400 static int
3401 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3402 {
3403         guint16 cnt=0, bc;
3404         guint8 wc;
3405         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3406         int fid=0;
3407
3408         WORD_COUNT;
3409
3410         /* read count */
3411         cnt = tvb_get_letohs(tvb, offset);
3412         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3413         offset += 2;
3414
3415         /* 8 reserved bytes */
3416         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3417         offset += 8;
3418
3419         /* If we have seen the request, then print which FID this refers to */
3420         /* first check if we have seen the request */
3421         if(si->sip != NULL && si->sip->frame_req>0){
3422                 fid=(int)si->sip->extra_info;
3423                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3424         }
3425
3426         BYTE_COUNT;
3427
3428         /* buffer format */
3429         CHECK_BYTE_COUNT(1);
3430         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3431         COUNT_BYTES(1);
3432
3433         /* data len */
3434         CHECK_BYTE_COUNT(2);
3435         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3436         COUNT_BYTES(2);
3437
3438         /* file data, might be DCERPC on a pipe */
3439         if(bc){
3440                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3441                     top_tree, offset, bc, bc, 0, fid);
3442                 bc = 0;
3443         }
3444
3445         END_OF_SMB
3446
3447         return offset;
3448 }
3449
3450 static int
3451 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3452 {
3453         guint16 cnt, bc;
3454         guint8 wc;
3455
3456         WORD_COUNT;
3457
3458         /* read count */
3459         cnt = tvb_get_letohs(tvb, offset);
3460         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3461         offset += 2;
3462
3463         /* 8 reserved bytes */
3464         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3465         offset += 8;
3466
3467         BYTE_COUNT;
3468
3469         /* buffer format */
3470         CHECK_BYTE_COUNT(1);
3471         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3472         COUNT_BYTES(1);
3473
3474         /* data len */
3475         CHECK_BYTE_COUNT(2);
3476         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3477         COUNT_BYTES(2);
3478
3479         END_OF_SMB
3480
3481         return offset;
3482 }
3483
3484
3485 static int
3486 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3487 {
3488         guint32 ofs=0;
3489         guint16 cnt=0, bc, fid=0;
3490         guint8 wc;
3491
3492         WORD_COUNT;
3493
3494         /* fid */
3495         fid = tvb_get_letohs(tvb, offset);
3496         add_fid(tvb, pinfo, tree, offset, 2, fid);
3497         offset += 2;
3498
3499         /* write count */
3500         cnt = tvb_get_letohs(tvb, offset);
3501         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3502         offset += 2;
3503
3504         /* offset */
3505         ofs = tvb_get_letohl(tvb, offset);
3506         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3507         offset += 4;
3508
3509         if (check_col(pinfo->cinfo, COL_INFO))
3510                 col_append_fstr(pinfo->cinfo, COL_INFO,
3511                                 ", %u byte%s at offset %u", cnt,
3512                                 (cnt == 1) ? "" : "s", ofs);
3513
3514         /* remaining */
3515         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3516         offset += 2;
3517
3518         BYTE_COUNT;
3519
3520         /* buffer format */
3521         CHECK_BYTE_COUNT(1);
3522         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3523         COUNT_BYTES(1);
3524
3525         /* data len */
3526         CHECK_BYTE_COUNT(2);
3527         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3528         COUNT_BYTES(2);
3529
3530         /* file data, might be DCERPC on a pipe */
3531         if (bc != 0) {
3532                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3533                     top_tree, offset, bc, bc, ofs, fid);
3534                 bc = 0;
3535         }
3536
3537         END_OF_SMB
3538
3539         return offset;
3540 }
3541
3542 static int
3543 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3544 {
3545         guint8 wc;
3546         guint16 bc, cnt;
3547
3548         WORD_COUNT;
3549
3550         /* write count */
3551         cnt = tvb_get_letohs(tvb, offset);
3552         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3553         offset += 2;
3554
3555         if (check_col(pinfo->cinfo, COL_INFO))
3556                 col_append_fstr(pinfo->cinfo, COL_INFO,
3557                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3558
3559         BYTE_COUNT;
3560
3561         END_OF_SMB
3562
3563         return offset;
3564 }
3565
3566 static int
3567 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3568 {
3569         guint8 wc;
3570         guint16 bc, fid;
3571
3572         WORD_COUNT;
3573
3574         /* fid */
3575         fid = tvb_get_letohs(tvb, offset);
3576         add_fid(tvb, pinfo, tree, offset, 2, fid);
3577         offset += 2;
3578
3579         /* lock count */
3580         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3581         offset += 4;
3582
3583         /* offset */
3584         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3585         offset += 4;
3586
3587         BYTE_COUNT;
3588
3589         END_OF_SMB
3590
3591         return offset;
3592 }
3593
3594 static int
3595 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3596 {
3597         smb_info_t *si = pinfo->private_data;
3598         int fn_len;
3599         const char *fn;
3600         guint8 wc;
3601         guint16 bc;
3602
3603         WORD_COUNT;
3604
3605         /* 2 reserved bytes */
3606         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3607         offset += 2;
3608
3609         /* Creation time */
3610         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3611
3612         BYTE_COUNT;
3613
3614         /* buffer format */
3615         CHECK_BYTE_COUNT(1);
3616         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3617         COUNT_BYTES(1);
3618
3619         /* directory name */
3620         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3621                 FALSE, FALSE, &bc);
3622         if (fn == NULL)
3623                 goto endofcommand;
3624         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3625                 fn);
3626         COUNT_BYTES(fn_len);
3627
3628         if (check_col(pinfo->cinfo, COL_INFO)) {
3629                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3630         }
3631
3632         END_OF_SMB
3633
3634         return offset;
3635 }
3636
3637 static int
3638 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3639 {
3640         smb_info_t *si = pinfo->private_data;
3641         int fn_len;
3642         const char *fn;
3643         guint8 wc;
3644         guint16 bc, fid;
3645
3646         WORD_COUNT;
3647
3648         /* fid */
3649         fid = tvb_get_letohs(tvb, offset);
3650         add_fid(tvb, pinfo, tree, offset, 2, fid);
3651         offset += 2;
3652
3653         BYTE_COUNT;
3654
3655         /* buffer format */
3656         CHECK_BYTE_COUNT(1);
3657         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3658         COUNT_BYTES(1);
3659
3660         /* file name */
3661         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3662                 FALSE, FALSE, &bc);
3663         if (fn == NULL)
3664                 goto endofcommand;
3665         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3666                 fn);
3667         COUNT_BYTES(fn_len);
3668
3669         END_OF_SMB
3670
3671         return offset;
3672 }
3673
3674 static const value_string seek_mode_vals[] = {
3675         {0,     "From Start Of File"},
3676         {1,     "From Current Position"},
3677         {2,     "From End Of File"},
3678         {0,     NULL}
3679 };
3680
3681 static int
3682 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3683 {
3684         guint8 wc;
3685         guint16 bc, fid;
3686
3687         WORD_COUNT;
3688
3689         /* fid */
3690         fid = tvb_get_letohs(tvb, offset);
3691         add_fid(tvb, pinfo, tree, offset, 2, fid);
3692         offset += 2;
3693
3694         /* Seek Mode */
3695         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3696         offset += 2;
3697
3698         /* offset */
3699         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3700         offset += 4;
3701
3702         BYTE_COUNT;
3703
3704         END_OF_SMB
3705
3706         return offset;
3707 }
3708
3709 static int
3710 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3711 {
3712         guint8 wc;
3713         guint16 bc;
3714
3715         WORD_COUNT;
3716
3717         /* offset */
3718         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3719         offset += 4;
3720
3721         BYTE_COUNT;
3722
3723         END_OF_SMB
3724
3725         return offset;
3726 }
3727
3728 static int
3729 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3730 {
3731         guint8 wc;
3732         guint16 bc, fid;
3733
3734         WORD_COUNT;
3735
3736         /* fid */
3737         fid = tvb_get_letohs(tvb, offset);
3738         add_fid(tvb, pinfo, tree, offset, 2, fid);
3739         offset += 2;
3740
3741         /* create time */
3742         offset = dissect_smb_datetime(tvb, tree, offset,
3743                 hf_smb_create_time,
3744                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3745
3746         /* access time */
3747         offset = dissect_smb_datetime(tvb, tree, offset,
3748                 hf_smb_access_time,
3749                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3750
3751         /* last write time */
3752         offset = dissect_smb_datetime(tvb, tree, offset,
3753                 hf_smb_last_write_time,
3754                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3755
3756         BYTE_COUNT;
3757
3758         END_OF_SMB
3759
3760         return offset;
3761 }
3762
3763 static int
3764 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3765 {
3766         guint8 wc;
3767         guint16 bc;
3768
3769         WORD_COUNT;
3770
3771         /* create time */
3772         offset = dissect_smb_datetime(tvb, tree, offset,
3773                 hf_smb_create_time,
3774                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3775
3776         /* access time */
3777         offset = dissect_smb_datetime(tvb, tree, offset,
3778                 hf_smb_access_time,
3779                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3780
3781         /* last write time */
3782         offset = dissect_smb_datetime(tvb, tree, offset,
3783                 hf_smb_last_write_time,
3784                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3785
3786         /* data size */
3787         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3788         offset += 4;
3789
3790         /* allocation size */
3791         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3792         offset += 4;
3793
3794         /* File Attributes */
3795         offset = dissect_file_attributes(tvb, tree, offset, 2);
3796
3797         BYTE_COUNT;
3798
3799         END_OF_SMB
3800
3801         return offset;
3802 }
3803
3804 static int
3805 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3806 {
3807         guint8 wc;
3808         guint16 cnt=0;
3809         guint16 bc, fid;
3810
3811         WORD_COUNT;
3812
3813         /* fid */
3814         fid = tvb_get_letohs(tvb, offset);
3815         add_fid(tvb, pinfo, tree, offset, 2, fid);
3816         offset += 2;
3817
3818         /* write count */
3819         cnt = tvb_get_letohs(tvb, offset);
3820         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3821         offset += 2;
3822
3823         /* offset */
3824         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3825         offset += 4;
3826
3827         /* last write time */
3828         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3829
3830         if(wc==12){
3831                 /* 12 reserved bytes */
3832                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3833                 offset += 12;
3834         }
3835
3836         BYTE_COUNT;
3837
3838         /* 1 pad byte */
3839         CHECK_BYTE_COUNT(1);
3840         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3841         COUNT_BYTES(1);
3842
3843         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3844         bc = 0; /* XXX */
3845
3846         END_OF_SMB
3847
3848         return offset;
3849 }
3850
3851 static int
3852 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3853 {
3854         guint8 wc;
3855         guint16 bc;
3856
3857         WORD_COUNT;
3858
3859         /* write count */
3860         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3861         offset += 2;
3862
3863         BYTE_COUNT;
3864
3865         END_OF_SMB
3866
3867         return offset;
3868 }
3869
3870 static int
3871 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3872 {
3873         guint8 wc;
3874         guint16 bc, fid;
3875         guint32 to;
3876
3877         WORD_COUNT;
3878
3879         /* fid */
3880         fid = tvb_get_letohs(tvb, offset);
3881         add_fid(tvb, pinfo, tree, offset, 2, fid);
3882         offset += 2;
3883
3884         /* offset */
3885         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3886         offset += 4;
3887
3888         /* max count */
3889         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3890         offset += 2;
3891
3892         /* min count */
3893         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3894         offset += 2;
3895
3896         /* timeout */
3897         to = tvb_get_letohl(tvb, offset);
3898         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3899         offset += 4;
3900
3901         /* 2 reserved bytes */
3902         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3903         offset += 2;
3904
3905         if(wc==10){
3906                 /* high offset */
3907                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3908                 offset += 4;
3909         }
3910
3911         BYTE_COUNT;
3912
3913         END_OF_SMB
3914
3915         return offset;
3916 }
3917
3918 static int
3919 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3920 {
3921         guint8 wc;
3922         guint16 bc;
3923
3924         WORD_COUNT;
3925
3926         /* units */
3927         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3928         offset += 2;
3929
3930         /* bpu */
3931         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3932         offset += 2;
3933
3934         /* block size */
3935         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3936         offset += 2;
3937
3938         /* free units */
3939         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3940         offset += 2;
3941
3942         /* 2 reserved bytes */
3943         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3944         offset += 2;
3945
3946         BYTE_COUNT;
3947
3948         END_OF_SMB
3949
3950         return offset;
3951 }
3952
3953 static int
3954 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3955 {
3956         guint8 wc;
3957         guint16 bc, fid;
3958
3959         WORD_COUNT;
3960
3961         /* fid */
3962         fid = tvb_get_letohs(tvb, offset);
3963         add_fid(tvb, pinfo, tree, offset, 2, fid);
3964         offset += 2;
3965
3966         /* offset */
3967         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3968         offset += 4;
3969
3970         /* max count */
3971         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3972         offset += 2;
3973
3974         /* min count */
3975         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3976         offset += 2;
3977
3978         /* 6 reserved bytes */
3979         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3980         offset += 6;
3981
3982         BYTE_COUNT;
3983
3984         END_OF_SMB
3985
3986         return offset;
3987 }
3988
3989 static int
3990 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3991 {
3992         guint16 datalen=0, bc;
3993         guint8 wc;
3994
3995         WORD_COUNT;
3996
3997         /* offset */
3998         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3999         offset += 4;
4000
4001         /* count */
4002         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4003         offset += 2;
4004
4005         /* 2 reserved bytes */
4006         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4007         offset += 2;
4008
4009         /* data compaction mode */
4010         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4011         offset += 2;
4012
4013         /* 2 reserved bytes */
4014         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4015         offset += 2;
4016
4017         /* data len */
4018         datalen = tvb_get_letohs(tvb, offset);
4019         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4020         offset += 2;
4021
4022         /* data offset */
4023         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4024         offset += 2;
4025
4026         BYTE_COUNT;
4027
4028         /* file data */
4029         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4030         bc = 0;
4031
4032         END_OF_SMB
4033
4034         return offset;
4035 }
4036
4037
4038 static const true_false_string tfs_write_mode_write_through = {
4039         "WRITE THROUGH requested",
4040         "Write through not requested"
4041 };
4042 static const true_false_string tfs_write_mode_return_remaining = {
4043         "RETURN REMAINING (pipe/dev) requested",
4044         "DON'T return remaining (pipe/dev)"
4045 };
4046 static const true_false_string tfs_write_mode_raw = {
4047         "Use WriteRawNamedPipe (pipe)",
4048         "DON'T use WriteRawNamedPipe (pipe)"
4049 };
4050 static const true_false_string tfs_write_mode_message_start = {
4051         "This is the START of a MESSAGE (pipe)",
4052         "This is NOT the start of a message (pipe)"
4053 };
4054 static const true_false_string tfs_write_mode_connectionless = {
4055         "CONNECTIONLESS mode requested",
4056         "Connectionless mode NOT requested"
4057 };
4058
4059 #define WRITE_MODE_CONNECTIONLESS       0x0080
4060 #define WRITE_MODE_MESSAGE_START        0x0008
4061 #define WRITE_MODE_RAW                  0x0004
4062 #define WRITE_MODE_RETURN_REMAINING     0x0002
4063 #define WRITE_MODE_WRITE_THROUGH        0x0001
4064
4065 static int
4066 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4067 {
4068         guint16 mask;
4069         proto_item *item = NULL;
4070         proto_tree *tree = NULL;
4071
4072         mask = tvb_get_letohs(tvb, offset);
4073
4074         if(parent_tree){
4075                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4076                         "Write Mode: 0x%04x", mask);
4077                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4078         }
4079
4080         if(bm&WRITE_MODE_CONNECTIONLESS){
4081                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4082                         tvb, offset, 2, mask);
4083         }
4084         if(bm&WRITE_MODE_MESSAGE_START){
4085                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4086                         tvb, offset, 2, mask);
4087         }
4088         if(bm&WRITE_MODE_RAW){
4089                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4090                         tvb, offset, 2, mask);
4091         }
4092         if(bm&WRITE_MODE_RETURN_REMAINING){
4093                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4094                         tvb, offset, 2, mask);
4095         }
4096         if(bm&WRITE_MODE_WRITE_THROUGH){
4097                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4098                         tvb, offset, 2, mask);
4099         }
4100
4101         offset += 2;
4102         return offset;
4103 }
4104
4105 static int
4106 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4107 {
4108         guint32 to;
4109         guint16 datalen=0, bc, fid;
4110         guint8 wc;
4111
4112         WORD_COUNT;
4113
4114         /* fid */
4115         fid = tvb_get_letohs(tvb, offset);
4116         add_fid(tvb, pinfo, tree, offset, 2, fid);
4117         offset += 2;
4118
4119         /* total data length */
4120         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4121         offset += 2;
4122
4123         /* 2 reserved bytes */
4124         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4125         offset += 2;
4126
4127         /* offset */
4128         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4129         offset += 4;
4130
4131         /* timeout */
4132         to = tvb_get_letohl(tvb, offset);
4133         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4134         offset += 4;
4135
4136         /* mode */
4137         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4138
4139         /* 4 reserved bytes */
4140         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4141         offset += 4;
4142
4143         /* data len */
4144         datalen = tvb_get_letohs(tvb, offset);
4145         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4146         offset += 2;
4147
4148         /* data offset */
4149         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4150         offset += 2;
4151
4152         BYTE_COUNT;
4153
4154         /* file data */
4155         /* XXX - use the data offset to determine where the data starts? */
4156         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4157         bc = 0;
4158
4159         END_OF_SMB
4160
4161         return offset;
4162 }
4163
4164 static int
4165 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4166 {
4167         guint8 wc;
4168         guint16 bc;
4169
4170         WORD_COUNT;
4171
4172         /* remaining */
4173         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4174         offset += 2;
4175
4176         BYTE_COUNT;
4177
4178         END_OF_SMB
4179
4180         return offset;
4181 }
4182
4183 static int
4184 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4185 {
4186         guint32 to;
4187         guint16 datalen=0, bc, fid;
4188         guint8 wc;
4189
4190         WORD_COUNT;
4191
4192         /* fid */
4193         fid = tvb_get_letohs(tvb, offset);
4194         add_fid(tvb, pinfo, tree, offset, 2, fid);
4195         offset += 2;
4196
4197         /* total data length */
4198         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4199         offset += 2;
4200
4201         /* 2 reserved bytes */
4202         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4203         offset += 2;
4204
4205         /* offset */
4206         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4207         offset += 4;
4208
4209         /* timeout */
4210         to = tvb_get_letohl(tvb, offset);
4211         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4212         offset += 4;
4213
4214         /* mode */
4215         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4216
4217         /* request mask */
4218         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4219         offset += 4;
4220
4221         /* data len */
4222         datalen = tvb_get_letohs(tvb, offset);
4223         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4224         offset += 2;
4225
4226         /* data offset */
4227         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4228         offset += 2;
4229
4230         BYTE_COUNT;
4231
4232         /* file data */
4233         /* XXX - use the data offset to determine where the data starts? */
4234         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4235         bc = 0;
4236
4237         END_OF_SMB
4238
4239         return offset;
4240 }
4241
4242 static int
4243 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4244 {
4245         guint8 wc;
4246         guint16 bc;
4247
4248         WORD_COUNT;
4249
4250         /* response mask */
4251         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4252         offset += 4;
4253
4254         BYTE_COUNT;
4255
4256         END_OF_SMB
4257
4258         return offset;
4259 }
4260
4261 static int
4262 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4263 {
4264         guint8 wc;
4265         guint16 bc;
4266
4267         WORD_COUNT;
4268
4269         /* sid */
4270         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4271         offset += 2;
4272
4273         BYTE_COUNT;
4274
4275         END_OF_SMB
4276
4277         return offset;
4278 }
4279
4280 static int
4281 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4282     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4283     gboolean has_find_id)
4284 {
4285         proto_item *item = NULL;
4286         proto_tree *tree = NULL;
4287         smb_info_t *si = pinfo->private_data;
4288         int fn_len;
4289         const char *fn;
4290         char fname[11+1];
4291
4292         if(parent_tree){
4293                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4294                         "Resume Key");
4295                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4296         }
4297
4298         /* reserved byte */
4299         CHECK_BYTE_COUNT_SUBR(1);
4300         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4301         COUNT_BYTES_SUBR(1);
4302
4303         /* file name */
4304         fn_len = 11;
4305         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4306                 TRUE, TRUE, bcp);
4307         CHECK_STRING_SUBR(fn);
4308         /* ensure that it's null-terminated */
4309         strncpy(fname, fn, 11);
4310         fname[11] = '\0';
4311         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4312                 fname);
4313         COUNT_BYTES_SUBR(fn_len);
4314
4315         if (has_find_id) {
4316                 CHECK_BYTE_COUNT_SUBR(1);
4317                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4318                 COUNT_BYTES_SUBR(1);
4319
4320                 /* server cookie */
4321                 CHECK_BYTE_COUNT_SUBR(4);
4322                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4323                 COUNT_BYTES_SUBR(4);
4324         } else {
4325                 /* server cookie */
4326                 CHECK_BYTE_COUNT_SUBR(5);
4327                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4328                 COUNT_BYTES_SUBR(5);
4329         }
4330
4331         /* client cookie */
4332         CHECK_BYTE_COUNT_SUBR(4);
4333         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4334         COUNT_BYTES_SUBR(4);
4335
4336         *trunc = FALSE;
4337         return offset;
4338 }
4339
4340 static int
4341 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4342     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4343     gboolean has_find_id)
4344 {
4345         proto_item *item = NULL;
4346         proto_tree *tree = NULL;
4347         smb_info_t *si = pinfo->private_data;
4348         int fn_len;
4349         const char *fn;
4350         char fname[13+1];
4351
4352         if(parent_tree){
4353                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4354                         "Directory Information");
4355                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4356         }
4357
4358         /* resume key */
4359         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4360             trunc, has_find_id);
4361         if (*trunc)
4362                 return offset;
4363
4364         /* File Attributes */
4365         CHECK_BYTE_COUNT_SUBR(1);
4366         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4367         *bcp -= 1;
4368
4369         /* last write time */
4370         CHECK_BYTE_COUNT_SUBR(4);
4371         offset = dissect_smb_datetime(tvb, tree, offset,
4372                 hf_smb_last_write_time,
4373                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4374                 TRUE);
4375         *bcp -= 4;
4376
4377         /* File Size */
4378         CHECK_BYTE_COUNT_SUBR(4);
4379         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4380         COUNT_BYTES_SUBR(4);
4381
4382         /* file name */
4383         fn_len = 13;
4384         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4385                 TRUE, TRUE, bcp);
4386         CHECK_STRING_SUBR(fn);
4387         /* ensure that it's null-terminated */
4388         strncpy(fname, fn, 13);
4389         fname[13] = '\0';
4390         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4391                 fname);
4392         COUNT_BYTES_SUBR(fn_len);
4393
4394         *trunc = FALSE;
4395         return offset;
4396 }
4397
4398
4399 static int
4400 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4401     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4402     gboolean has_find_id)
4403 {
4404         smb_info_t *si = pinfo->private_data;
4405         int fn_len;
4406         const char *fn;
4407         guint16 rkl;
4408         guint8 wc;
4409         guint16 bc;
4410         gboolean trunc;
4411
4412         WORD_COUNT;
4413
4414         /* max count */
4415         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4416         offset += 2;
4417
4418         /* Search Attributes */
4419         offset = dissect_search_attributes(tvb, tree, offset);
4420
4421         BYTE_COUNT;
4422
4423         /* buffer format */
4424         CHECK_BYTE_COUNT(1);
4425         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4426         COUNT_BYTES(1);
4427
4428         /* file name */
4429         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4430                 TRUE, FALSE, &bc);
4431         if (fn == NULL)
4432                 goto endofcommand;
4433         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4434                 fn);
4435         COUNT_BYTES(fn_len);
4436
4437         if (check_col(pinfo->cinfo, COL_INFO)) {
4438                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4439         }
4440
4441         /* buffer format */
4442         CHECK_BYTE_COUNT(1);
4443         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4444         COUNT_BYTES(1);
4445
4446         /* resume key length */
4447         CHECK_BYTE_COUNT(2);
4448         rkl = tvb_get_letohs(tvb, offset);
4449         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4450         COUNT_BYTES(2);
4451
4452         /* resume key */
4453         if(rkl){
4454                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4455                     &bc, &trunc, has_find_id);
4456                 if (trunc)
4457                         goto endofcommand;
4458         }
4459
4460         END_OF_SMB
4461
4462         return offset;
4463 }
4464
4465 static int
4466 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4467     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4468 {
4469         return dissect_search_find_request(tvb, pinfo, tree, offset,
4470             smb_tree, FALSE);
4471 }
4472
4473 static int
4474 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4475     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4476 {
4477         return dissect_search_find_request(tvb, pinfo, tree, offset,
4478             smb_tree, TRUE);
4479 }
4480
4481 static int
4482 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4483     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4484 {
4485         return dissect_search_find_request(tvb, pinfo, tree, offset,
4486             smb_tree, TRUE);
4487 }
4488
4489 static int
4490 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4491     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4492     gboolean has_find_id)
4493 {
4494         guint16 count=0;
4495         guint8 wc;
4496         guint16 bc;
4497         gboolean trunc;
4498
4499         WORD_COUNT;
4500
4501         /* count */
4502         count = tvb_get_letohs(tvb, offset);
4503         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4504         offset += 2;
4505
4506         BYTE_COUNT;
4507
4508         /* buffer format */
4509         CHECK_BYTE_COUNT(1);
4510         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4511         COUNT_BYTES(1);
4512
4513         /* data len */
4514         CHECK_BYTE_COUNT(2);
4515         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4516         COUNT_BYTES(2);
4517
4518         while(count--){
4519                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4520                     &bc, &trunc, has_find_id);
4521                 if (trunc)
4522                         goto endofcommand;
4523         }
4524
4525         END_OF_SMB
4526
4527         return offset;
4528 }
4529
4530 static int
4531 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4532 {
4533         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4534             FALSE);
4535 }
4536
4537 static int
4538 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4539 {
4540         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4541             TRUE);
4542 }
4543
4544 static int
4545 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4546     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4547 {
4548         guint8 wc;
4549         guint16 bc;
4550         guint16 data_len;
4551
4552         WORD_COUNT;
4553
4554         /* reserved */
4555         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4556         offset += 2;
4557
4558         BYTE_COUNT;
4559
4560         /* buffer format */
4561         CHECK_BYTE_COUNT(1);
4562         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4563         COUNT_BYTES(1);
4564
4565         /* data len */
4566         CHECK_BYTE_COUNT(2);
4567         data_len = tvb_get_ntohs(tvb, offset);
4568         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4569         COUNT_BYTES(2);
4570
4571         if (data_len != 0) {
4572                 CHECK_BYTE_COUNT(data_len);
4573                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4574                     data_len, TRUE);
4575                 COUNT_BYTES(data_len);
4576         }
4577
4578         END_OF_SMB
4579
4580         return offset;
4581 }
4582
4583 static const value_string locking_ol_vals[] = {
4584         {0,     "Client is not holding oplock on this file"},
4585         {1,     "Level 2 oplock currently held by client"},
4586         {0, NULL}
4587 };
4588
4589 static const true_false_string tfs_lock_type_large = {
4590         "Large file locking format requested",
4591         "Large file locking format not requested"
4592 };
4593 static const true_false_string tfs_lock_type_cancel = {
4594         "Cancel outstanding lock request",
4595         "Don't cancel outstanding lock request"
4596 };
4597 static const true_false_string tfs_lock_type_change = {
4598         "Change lock type",
4599         "Don't change lock type"
4600 };
4601 static const true_false_string tfs_lock_type_oplock = {
4602         "This is an oplock break notification/response",
4603         "This is not an oplock break notification/response"
4604 };
4605 static const true_false_string tfs_lock_type_shared = {
4606         "This is a shared lock",
4607         "This is an exclusive lock"
4608 };
4609 static int
4610 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4611 {
4612         guint8  wc, cmd=0xff, lt=0;
4613         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4614         guint32 to;
4615         proto_item *litem = NULL;
4616         proto_tree *ltree = NULL;
4617         proto_item *it = NULL;
4618         proto_tree *tr = NULL;
4619         int old_offset = offset;
4620
4621         WORD_COUNT;
4622
4623         /* next smb command */
4624         cmd = tvb_get_guint8(tvb, offset);
4625         if(cmd!=0xff){
4626                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4627         } else {
4628                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4629         }
4630         offset += 1;
4631
4632         /* reserved byte */
4633         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4634         offset += 1;
4635
4636         /* andxoffset */
4637         andxoffset = tvb_get_letohs(tvb, offset);
4638         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4639         offset += 2;
4640
4641         /* fid */
4642         fid = tvb_get_letohs(tvb, offset);
4643         add_fid(tvb, pinfo, tree, offset, 2, fid);
4644         offset += 2;
4645
4646         /* lock type */
4647         lt = tvb_get_guint8(tvb, offset);
4648         if(tree){
4649                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4650                         "Lock Type: 0x%02x", lt);
4651                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4652         }
4653         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4654                 tvb, offset, 1, lt);
4655         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4656                 tvb, offset, 1, lt);
4657         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4658                 tvb, offset, 1, lt);
4659         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4660                 tvb, offset, 1, lt);
4661         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4662                 tvb, offset, 1, lt);
4663         offset += 1;
4664
4665         /* oplock level */
4666         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4667         offset += 1;
4668
4669         /* timeout */
4670         to = tvb_get_letohl(tvb, offset);
4671         if (to == 0)
4672                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4673         else if (to == 0xffffffff)
4674                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4675         else
4676                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4677         offset += 4;
4678
4679         /* number of unlocks */
4680         un = tvb_get_letohs(tvb, offset);
4681         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4682         offset += 2;
4683
4684         /* number of locks */
4685         ln = tvb_get_letohs(tvb, offset);
4686         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4687         offset += 2;
4688
4689         BYTE_COUNT;
4690
4691         /* unlocks */
4692         if(un){
4693                 old_offset = offset;
4694
4695                 it = proto_tree_add_text(tree, tvb, offset, -1,
4696                         "Unlocks");
4697                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4698                 while(un--){
4699                         proto_item *litem = NULL;
4700                         proto_tree *ltree = NULL;
4701                         if(lt&0x10){
4702                                 /* large lock format */
4703                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4704                                         "Unlock");
4705                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4706
4707                                 /* PID */
4708                                 CHECK_BYTE_COUNT(2);
4709                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4710                                 COUNT_BYTES(2);
4711
4712                                 /* 2 reserved bytes */
4713                                 CHECK_BYTE_COUNT(2);
4714                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4715                                 COUNT_BYTES(2);
4716
4717                                 /* offset */
4718                                 CHECK_BYTE_COUNT(8);
4719                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4720                                 COUNT_BYTES(8);
4721
4722                                 /* length */
4723                                 CHECK_BYTE_COUNT(8);
4724                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4725                                 COUNT_BYTES(8);
4726                         } else {
4727                                 /* normal lock format */
4728                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4729                                         "Unlock");
4730                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4731
4732                                 /* PID */
4733                                 CHECK_BYTE_COUNT(2);
4734                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4735                                 COUNT_BYTES(2);
4736
4737                                 /* offset */
4738                                 CHECK_BYTE_COUNT(4);
4739                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4740                                 COUNT_BYTES(4);
4741
4742                                 /* lock count */
4743                                 CHECK_BYTE_COUNT(4);
4744                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4745                                 COUNT_BYTES(4);
4746                         }
4747                 }
4748                 proto_item_set_len(it, offset-old_offset);
4749                 it = NULL;
4750         }
4751
4752         /* locks */
4753         if(ln){
4754                 old_offset = offset;
4755
4756                 it = proto_tree_add_text(tree, tvb, offset, -1,
4757                         "Locks");
4758                 tr = proto_item_add_subtree(it, ett_smb_locks);
4759                 while(ln--){
4760                         proto_item *litem = NULL;
4761                         proto_tree *ltree = NULL;
4762                         if(lt&0x10){
4763                                 /* large lock format */
4764                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4765                                         "Lock");
4766                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4767
4768                                 /* PID */
4769                                 CHECK_BYTE_COUNT(2);
4770                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4771                                 COUNT_BYTES(2);
4772
4773                                 /* 2 reserved bytes */
4774                                 CHECK_BYTE_COUNT(2);
4775                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4776                                 COUNT_BYTES(2);
4777
4778                                 /* offset */
4779                                 CHECK_BYTE_COUNT(8);
4780                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4781                                 COUNT_BYTES(8);
4782
4783                                 /* length */
4784                                 CHECK_BYTE_COUNT(8);
4785                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4786                                 COUNT_BYTES(8);
4787                         } else {
4788                                 /* normal lock format */
4789                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4790                                         "Unlock");
4791                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4792
4793                                 /* PID */
4794                                 CHECK_BYTE_COUNT(2);
4795                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4796                                 COUNT_BYTES(2);
4797
4798                                 /* offset */
4799                                 CHECK_BYTE_COUNT(4);
4800                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4801                                 COUNT_BYTES(4);
4802
4803                                 /* lock count */
4804                                 CHECK_BYTE_COUNT(4);
4805                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4806                                 COUNT_BYTES(4);
4807                         }
4808                 }
4809                 proto_item_set_len(it, offset-old_offset);
4810                 it = NULL;
4811         }
4812
4813         END_OF_SMB
4814
4815         if (it != NULL) {
4816                 /*
4817                  * We ran out of byte count in the middle of dissecting
4818                  * the locks or the unlocks; set the site of the item
4819                  * we were dissecting.
4820                  */
4821                 proto_item_set_len(it, offset-old_offset);
4822         }
4823
4824         /* call AndXCommand (if there are any) */
4825         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4826
4827         return offset;
4828 }
4829
4830 static int
4831 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4832 {
4833         guint8  wc, cmd=0xff;
4834         guint16 andxoffset=0;
4835         guint16 bc;
4836
4837         WORD_COUNT;
4838
4839         /* next smb command */
4840         cmd = tvb_get_guint8(tvb, offset);
4841         if(cmd!=0xff){
4842                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4843         } else {
4844                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4845         }
4846         offset += 1;
4847
4848         /* reserved byte */
4849         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4850         offset += 1;
4851
4852         /* andxoffset */
4853         andxoffset = tvb_get_letohs(tvb, offset);
4854         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4855         offset += 2;
4856
4857         BYTE_COUNT;
4858
4859         END_OF_SMB
4860
4861         /* call AndXCommand (if there are any) */
4862         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4863
4864         return offset;
4865 }
4866
4867
4868 static const value_string oa_open_vals[] = {
4869         { 0,            "No action taken?"},
4870         { 1,            "The file existed and was opened"},
4871         { 2,            "The file did not exist but was created"},
4872         { 3,            "The file existed and was truncated"},
4873         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4874         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4875         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4876         {0,     NULL}
4877 };
4878 static const true_false_string tfs_oa_lock = {
4879         "File is currently opened only by this user",
4880         "File is opened by another user (or mode not supported by server)"
4881 };
4882 static int
4883 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4884 {
4885         guint16 mask;
4886         proto_item *item = NULL;
4887         proto_tree *tree = NULL;
4888
4889         mask = tvb_get_letohs(tvb, offset);
4890
4891         if(parent_tree){
4892                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4893                         "Action: 0x%04x", mask);
4894                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4895         }
4896
4897         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4898                 tvb, offset, 2, mask);
4899         proto_tree_add_uint(tree, hf_smb_open_action_open,
4900                 tvb, offset, 2, mask);
4901
4902         offset += 2;
4903
4904         return offset;
4905 }
4906
4907 static const true_false_string tfs_open_flags_add_info = {
4908         "Additional information requested",
4909         "Additional information not requested"
4910 };
4911 static const true_false_string tfs_open_flags_ex_oplock = {
4912         "Exclusive oplock requested",
4913         "Exclusive oplock not requested"
4914 };
4915 static const true_false_string tfs_open_flags_batch_oplock = {
4916         "Batch oplock requested",
4917         "Batch oplock not requested"
4918 };
4919 static const true_false_string tfs_open_flags_ealen = {
4920         "Total length of EAs requested",
4921         "Total length of EAs not requested"
4922 };
4923 static int
4924 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4925 {
4926         guint16 mask;
4927         proto_item *item = NULL;
4928         proto_tree *tree = NULL;
4929
4930         mask = tvb_get_letohs(tvb, offset);
4931
4932         if(parent_tree){
4933                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4934                         "Flags: 0x%04x", mask);
4935                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4936         }
4937
4938         if(bm&0x0001){
4939                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4940                         tvb, offset, 2, mask);
4941         }
4942         if(bm&0x0002){
4943                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4944                         tvb, offset, 2, mask);
4945         }
4946         if(bm&0x0004){
4947                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4948                         tvb, offset, 2, mask);
4949         }
4950         if(bm&0x0008){
4951                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4952                         tvb, offset, 2, mask);
4953         }
4954
4955         offset += 2;
4956
4957         return offset;
4958 }
4959
4960 static const value_string filetype_vals[] = {
4961         { 0,            "Disk file or directory"},
4962         { 1,            "Named pipe in byte mode"},
4963         { 2,            "Named pipe in message mode"},
4964         { 3,            "Spooled printer"},
4965         {0, NULL}
4966 };
4967 static int
4968 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4969 {
4970         guint8  wc, cmd=0xff;
4971         guint16 andxoffset=0, bc;
4972         smb_info_t *si = pinfo->private_data;
4973         int fn_len;
4974         const char *fn;
4975
4976         WORD_COUNT;
4977
4978         /* next smb command */
4979         cmd = tvb_get_guint8(tvb, offset);
4980         if(cmd!=0xff){
4981                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4982         } else {
4983                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4984         }
4985         offset += 1;
4986
4987         /* reserved byte */
4988         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4989         offset += 1;
4990
4991         /* andxoffset */
4992         andxoffset = tvb_get_letohs(tvb, offset);
4993         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4994         offset += 2;
4995
4996         /* open flags */
4997         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
4998
4999         /* desired access */
5000         offset = dissect_access(tvb, tree, offset, "Desired");
5001
5002         /* Search Attributes */
5003         offset = dissect_search_attributes(tvb, tree, offset);
5004
5005         /* File Attributes */
5006         offset = dissect_file_attributes(tvb, tree, offset, 2);
5007
5008         /* creation time */
5009         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5010
5011         /* open function */
5012         offset = dissect_open_function(tvb, tree, offset);
5013
5014         /* allocation size */
5015         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5016         offset += 4;
5017
5018         /* 8 reserved bytes */
5019         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5020         offset += 8;
5021
5022         BYTE_COUNT;
5023
5024         /* file name */
5025         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5026                 FALSE, FALSE, &bc);
5027         if (fn == NULL)
5028                 goto endofcommand;
5029         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5030                 fn);
5031         COUNT_BYTES(fn_len);
5032
5033         if (check_col(pinfo->cinfo, COL_INFO)) {
5034                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5035         }
5036
5037         END_OF_SMB
5038
5039         /* call AndXCommand (if there are any) */
5040         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5041
5042         return offset;
5043 }
5044
5045 static const true_false_string tfs_ipc_state_nonblocking = {
5046         "Reads/writes return immediately if no data available",
5047         "Reads/writes block if no data available"
5048 };
5049 static const value_string ipc_state_endpoint_vals[] = {
5050         { 0,            "Consumer end of pipe"},
5051         { 1,            "Server end of pipe"},
5052         {0,     NULL}
5053 };
5054 static const value_string ipc_state_pipe_type_vals[] = {
5055         { 0,            "Byte stream pipe"},
5056         { 1,            "Message pipe"},
5057         {0,     NULL}
5058 };
5059 static const value_string ipc_state_read_mode_vals[] = {
5060         { 0,            "Read pipe as a byte stream"},
5061         { 1,            "Read messages from pipe"},
5062         {0,     NULL}
5063 };
5064
5065 int
5066 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5067     gboolean setstate)
5068 {
5069         guint16 mask;
5070         proto_item *item = NULL;
5071         proto_tree *tree = NULL;
5072
5073         mask = tvb_get_letohs(tvb, offset);
5074
5075         if(parent_tree){
5076                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5077                         "IPC State: 0x%04x", mask);
5078                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5079         }
5080
5081         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5082                 tvb, offset, 2, mask);
5083         if (!setstate) {
5084                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5085                         tvb, offset, 2, mask);
5086                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5087                         tvb, offset, 2, mask);
5088         }
5089         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5090                 tvb, offset, 2, mask);
5091         if (!setstate) {
5092                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5093                         tvb, offset, 2, mask);
5094         }
5095
5096         offset += 2;
5097
5098         return offset;
5099 }
5100
5101 static int
5102 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5103 {
5104         guint8  wc, cmd=0xff;
5105         guint16 andxoffset=0, bc;
5106         guint16 fid;
5107
5108         WORD_COUNT;
5109
5110         /* next smb command */
5111         cmd = tvb_get_guint8(tvb, offset);
5112         if(cmd!=0xff){
5113                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5114         } else {
5115                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5116         }
5117         offset += 1;
5118
5119         /* reserved byte */
5120         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5121         offset += 1;
5122
5123         /* andxoffset */
5124         andxoffset = tvb_get_letohs(tvb, offset);
5125         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5126         offset += 2;
5127
5128         /* fid */
5129         fid = tvb_get_letohs(tvb, offset);
5130         add_fid(tvb, pinfo, tree, offset, 2, fid);
5131         offset += 2;
5132
5133         /* File Attributes */
5134         offset = dissect_file_attributes(tvb, tree, offset, 2);
5135
5136         /* last write time */
5137         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5138
5139         /* File Size */
5140         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5141         offset += 4;
5142
5143         /* granted access */
5144         offset = dissect_access(tvb, tree, offset, "Granted");
5145
5146         /* File Type */
5147         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5148         offset += 2;
5149
5150         /* IPC State */
5151         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5152
5153         /* open_action */
5154         offset = dissect_open_action(tvb, tree, offset);
5155
5156         /* server fid */
5157         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5158         offset += 4;
5159
5160         /* 2 reserved bytes */
5161         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5162         offset += 2;
5163
5164         BYTE_COUNT;
5165
5166         END_OF_SMB
5167
5168         /* call AndXCommand (if there are any) */
5169         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5170
5171         return offset;
5172 }
5173
5174 static int
5175 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5176 {
5177         guint8  wc, cmd=0xff;
5178         guint16 andxoffset=0, bc, maxcnt = 0;
5179         guint32 ofs = 0;
5180         smb_info_t *si;
5181         unsigned int fid;
5182
5183         WORD_COUNT;
5184
5185         /* next smb command */
5186         cmd = tvb_get_guint8(tvb, offset);
5187         if(cmd!=0xff){
5188                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5189         } else {
5190                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5191         }
5192         offset += 1;
5193
5194         /* reserved byte */
5195         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5196         offset += 1;
5197
5198         /* andxoffset */
5199         andxoffset = tvb_get_letohs(tvb, offset);
5200         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5201         offset += 2;
5202
5203         /* fid */
5204         fid = tvb_get_letohs(tvb, offset);
5205         add_fid(tvb, pinfo, tree, offset, 2, fid);
5206         offset += 2;
5207         if (!pinfo->fd->flags.visited) {
5208                 /* remember the FID for the processing of the response */
5209                 si = (smb_info_t *)pinfo->private_data;
5210                 si->sip->extra_info=(void *)fid;
5211         }
5212
5213         /* offset */
5214         ofs = tvb_get_letohl(tvb, offset);
5215         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5216         offset += 4;
5217
5218         /* max count */
5219         maxcnt = tvb_get_letohs(tvb, offset);
5220         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5221         offset += 2;
5222
5223         if (check_col(pinfo->cinfo, COL_INFO))
5224                 col_append_fstr(pinfo->cinfo, COL_INFO,
5225                                 ", %u byte%s at offset %u", maxcnt,
5226                                 (maxcnt == 1) ? "" : "s", ofs);
5227
5228         /* min count */
5229         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5230         offset += 2;
5231
5232         /* XXX - max count high */
5233         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5234         offset += 4;
5235
5236         /* remaining */
5237         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5238         offset += 2;
5239
5240         if(wc==12){
5241                 /* high offset */
5242                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5243                 offset += 4;
5244         }
5245
5246         BYTE_COUNT;
5247
5248         END_OF_SMB
5249
5250         /* call AndXCommand (if there are any) */
5251         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5252
5253         return offset;
5254 }
5255
5256 static int
5257 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5258 {
5259         guint8  wc, cmd=0xff;
5260         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5261         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5262         int fid=0;
5263
5264         WORD_COUNT;
5265
5266         /* next smb command */
5267         cmd = tvb_get_guint8(tvb, offset);
5268         if(cmd!=0xff){
5269                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5270         } else {
5271                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5272         }
5273         offset += 1;
5274
5275         /* reserved byte */
5276         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5277         offset += 1;
5278
5279         /* andxoffset */
5280         andxoffset = tvb_get_letohs(tvb, offset);
5281         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5282         offset += 2;
5283
5284         /* If we have seen the request, then print which FID this refers to */
5285         /* first check if we have seen the request */
5286         if(si->sip != NULL && si->sip->frame_req>0){
5287                 fid=(int)si->sip->extra_info;
5288                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5289         }
5290
5291         /* remaining */
5292         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5293         offset += 2;
5294
5295         /* data compaction mode */
5296         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5297         offset += 2;
5298
5299         /* 2 reserved bytes */
5300         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5301         offset += 2;
5302
5303         /* data len */
5304         datalen = tvb_get_letohs(tvb, offset);
5305         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5306         offset += 2;
5307
5308         if (check_col(pinfo->cinfo, COL_INFO))
5309                 col_append_fstr(pinfo->cinfo, COL_INFO,
5310                                 ", %u byte%s", datalen,
5311                                 (datalen == 1) ? "" : "s");
5312
5313         /* data offset */
5314         dataoffset=tvb_get_letohs(tvb, offset);
5315         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5316         offset += 2;
5317
5318         /* 10 reserved bytes */
5319         /* XXX - first 2 bytes are data length high, not reserved */
5320         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5321         offset += 10;
5322
5323         BYTE_COUNT;
5324
5325         /* file data, might be DCERPC on a pipe */
5326         if(bc){
5327                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5328                     top_tree, offset, bc, datalen, 0, fid);
5329                 bc = 0;
5330         }
5331
5332         END_OF_SMB
5333
5334         /* call AndXCommand (if there are any) */
5335         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5336
5337         return offset;
5338 }
5339
5340 static int
5341 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5342 {
5343         guint32 ofs=0;
5344         guint8  wc, cmd=0xff;
5345         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5346         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5347         unsigned int fid=0;
5348         guint16 mode = 0;
5349
5350
5351         WORD_COUNT;
5352
5353         /* next smb command */
5354         cmd = tvb_get_guint8(tvb, offset);
5355         if(cmd!=0xff){
5356                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5357         } else {
5358                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5359         }
5360         offset += 1;
5361
5362         /* reserved byte */
5363         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5364         offset += 1;
5365
5366         /* andxoffset */
5367         andxoffset = tvb_get_letohs(tvb, offset);
5368         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5369         offset += 2;
5370
5371         /* fid */
5372         fid = tvb_get_letohs(tvb, offset);
5373         add_fid(tvb, pinfo, tree, offset, 2, fid);
5374         offset += 2;
5375         if (!pinfo->fd->flags.visited) {
5376                 /* remember the FID for the processing of the response */
5377                 si->sip->extra_info=(void *)fid;
5378         }
5379
5380         /* offset */
5381         ofs = tvb_get_letohl(tvb, offset);
5382         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5383         offset += 4;
5384
5385         /* reserved */
5386         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5387         offset += 4;
5388
5389         /* mode */
5390         mode = tvb_get_letohs(tvb, offset);
5391         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5392
5393         /* remaining */
5394         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5395         offset += 2;
5396
5397         /* XXX - data length high */
5398         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5399         offset += 2;
5400
5401         /* data len */
5402         datalen = tvb_get_letohs(tvb, offset);
5403         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5404         offset += 2;
5405
5406         /* data offset */
5407         dataoffset=tvb_get_letohs(tvb, offset);
5408         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5409         offset += 2;
5410
5411         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5412         if (check_col(pinfo->cinfo, COL_INFO))
5413                 col_append_fstr(pinfo->cinfo, COL_INFO,
5414                                 ", %u byte%s at offset %u", datalen,
5415                                 (datalen == 1) ? "" : "s", ofs);
5416
5417         if(wc==14){
5418                 /* high offset */
5419                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5420                 offset += 4;
5421         }
5422
5423         BYTE_COUNT;
5424
5425         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5426            the first two bytes of the payload is the length of the data
5427            also this tells us that this is indeed the IPC$ share
5428            (if we didnt already know that 
5429         */
5430         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5431                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5432                 offset += 2;
5433                 dataoffset += 2;
5434                 bc -= 2;
5435                 datalen -= 2;
5436                 if(si->sip){
5437                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5438                 }
5439         }
5440
5441         /* file data, might be DCERPC on a pipe */
5442         if (bc != 0) {
5443                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5444                     top_tree, offset, bc, datalen, 0, fid);
5445                 bc = 0;
5446         }
5447
5448         END_OF_SMB
5449
5450         /* call AndXCommand (if there are any) */
5451         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5452
5453         return offset;
5454 }
5455
5456 static int
5457 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5458 {
5459         guint8  wc, cmd=0xff;
5460         guint16 andxoffset=0, bc, datalen=0;
5461         smb_info_t *si;
5462
5463         WORD_COUNT;
5464
5465         /* next smb command */
5466         cmd = tvb_get_guint8(tvb, offset);
5467         if(cmd!=0xff){
5468                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5469         } else {
5470                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5471         }
5472         offset += 1;
5473
5474         /* reserved byte */
5475         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5476         offset += 1;
5477
5478         /* andxoffset */
5479         andxoffset = tvb_get_letohs(tvb, offset);
5480         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5481         offset += 2;
5482
5483         /* If we have seen the request, then print which FID this refers to */
5484         si = (smb_info_t *)pinfo->private_data;
5485         /* first check if we have seen the request */
5486         if(si->sip != NULL && si->sip->frame_req>0){
5487                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5488         }
5489
5490         /* write count */
5491         datalen = tvb_get_letohs(tvb, offset);
5492         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5493         offset += 2;
5494
5495         if (check_col(pinfo->cinfo, COL_INFO))
5496                 col_append_fstr(pinfo->cinfo, COL_INFO,
5497                                 ", %u byte%s", datalen,
5498                                 (datalen == 1) ? "" : "s");
5499
5500         /* remaining */
5501         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5502         offset += 2;
5503
5504         /* 4 reserved bytes */
5505         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5506         offset += 4;
5507
5508         BYTE_COUNT;
5509
5510         END_OF_SMB
5511
5512         /* call AndXCommand (if there are any) */
5513         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5514
5515         return offset;
5516 }
5517
5518
5519 static const true_false_string tfs_setup_action_guest = {
5520         "Logged in as GUEST",
5521         "Not logged in as GUEST"
5522 };
5523 static int
5524 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5525 {
5526         guint16 mask;
5527         proto_item *item = NULL;
5528         proto_tree *tree = NULL;
5529
5530         mask = tvb_get_letohs(tvb, offset);
5531
5532         if(parent_tree){
5533                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5534                         "Action: 0x%04x", mask);
5535                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5536         }
5537
5538         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5539                 tvb, offset, 2, mask);
5540
5541         offset += 2;
5542
5543         return offset;
5544 }
5545
5546
5547 static int
5548 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5549 {
5550         guint8  wc, cmd=0xff;
5551         guint16 bc;
5552         guint16 andxoffset=0;
5553         smb_info_t *si = pinfo->private_data;
5554         int an_len;
5555         const char *an;
5556         int dn_len;
5557         const char *dn;
5558         guint16 pwlen=0;
5559         guint16 sbloblen=0;
5560         guint16 apwlen=0, upwlen=0;
5561
5562         WORD_COUNT;
5563
5564         /* next smb command */
5565         cmd = tvb_get_guint8(tvb, offset);
5566         if(cmd!=0xff){
5567                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5568         } else {
5569                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5570         }
5571         offset += 1;
5572
5573         /* reserved byte */
5574         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5575         offset += 1;
5576
5577         /* andxoffset */
5578         andxoffset = tvb_get_letohs(tvb, offset);
5579         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5580         offset += 2;
5581
5582         /* Maximum Buffer Size */
5583         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5584         offset += 2;
5585
5586         /* Maximum Multiplex Count */
5587         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5588         offset += 2;
5589
5590         /* VC Number */
5591         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5592         offset += 2;
5593
5594         /* session key */
5595         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5596         offset += 4;
5597
5598         switch (wc) {
5599         case 10:
5600                 /* password length, ASCII*/
5601                 pwlen = tvb_get_letohs(tvb, offset);
5602                 proto_tree_add_uint(tree, hf_smb_password_len,
5603                         tvb, offset, 2, pwlen);
5604                 offset += 2;
5605
5606                 /* 4 reserved bytes */
5607                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5608                 offset += 4;
5609
5610                 break;
5611
5612         case 12:
5613                 /* security blob length */
5614                 sbloblen = tvb_get_letohs(tvb, offset);
5615                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5616                 offset += 2;
5617
5618                 /* 4 reserved bytes */
5619                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5620                 offset += 4;
5621
5622                 /* capabilities */
5623                 dissect_negprot_capabilities(tvb, tree, offset);
5624                 offset += 4;
5625
5626                 break;
5627
5628         case 13:
5629                 /* password length, ANSI*/
5630                 apwlen = tvb_get_letohs(tvb, offset);
5631                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5632                         tvb, offset, 2, apwlen);
5633                 offset += 2;
5634
5635                 /* password length, Unicode*/
5636                 upwlen = tvb_get_letohs(tvb, offset);
5637                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5638                         tvb, offset, 2, upwlen);
5639                 offset += 2;
5640
5641                 /* 4 reserved bytes */
5642                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5643                 offset += 4;
5644
5645                 /* capabilities */
5646                 dissect_negprot_capabilities(tvb, tree, offset);
5647                 offset += 4;
5648
5649                 break;
5650         }
5651
5652         BYTE_COUNT;
5653
5654         if (wc==12) {
5655                 proto_item *blob_item;
5656
5657                 /* security blob */
5658
5659                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5660                                                 tvb, offset, sbloblen, TRUE);
5661
5662                 /* As an optimization, because Windows is perverse,
5663                    we check to see if NTLMSSP is the first part of the 
5664                    blob, and if so, call the NTLMSSP dissector,
5665                    otherwise we call the GSS-API dissector. This is because
5666                    Windows can request RAW NTLMSSP, but will happily handle
5667                    a client that wraps NTLMSSP in SPNEGO
5668                 */
5669
5670                 if(sbloblen){
5671                         tvbuff_t *blob_tvb;
5672                         proto_tree *blob_tree;
5673
5674                         blob_tree = proto_item_add_subtree(blob_item, 
5675                                                            ett_smb_secblob);
5676                         CHECK_BYTE_COUNT(sbloblen);
5677
5678                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5679                                                   sbloblen);
5680
5681                         if (si && si->ct && si->ct->raw_ntlmssp && 
5682                             !strncmp("NTLMSSP", 
5683                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5684                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5685                                          blob_tree);
5686
5687                         }
5688                         else {
5689                           call_dissector(gssapi_handle, blob_tvb, 
5690                                          pinfo, blob_tree);
5691                         }
5692
5693                         COUNT_BYTES(sbloblen);
5694                 }
5695
5696                 /* OS */
5697                 an = get_unicode_or_ascii_string(tvb, &offset,
5698                         si->unicode, &an_len, FALSE, FALSE, &bc);
5699                 if (an == NULL)
5700                         goto endofcommand;
5701                 proto_tree_add_string(tree, hf_smb_os, tvb,
5702                         offset, an_len, an);
5703                 COUNT_BYTES(an_len);
5704
5705                 /* LANMAN */
5706                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5707                  * padding/null string/whatever in front of this. W2K doesn't
5708                  * appear to. I suspect that's a bug that got fixed; I also
5709                  * suspect that, in practice, nobody ever looks at that field
5710                  * because the bug didn't appear to get fixed until NT 5.0....
5711                  */
5712                 an = get_unicode_or_ascii_string(tvb, &offset,
5713                         si->unicode, &an_len, FALSE, FALSE, &bc);
5714                 if (an == NULL)
5715                         goto endofcommand;
5716                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5717                         offset, an_len, an);
5718                 COUNT_BYTES(an_len);
5719
5720                 /* Primary domain */
5721                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5722                  * byte in front of this, at least if all the strings are
5723                  * ASCII and the account name is empty. Another bug?
5724                  */
5725                 dn = get_unicode_or_ascii_string(tvb, &offset,
5726                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5727                 if (dn == NULL)
5728                         goto endofcommand;
5729                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5730                         offset, dn_len, dn);
5731                 COUNT_BYTES(dn_len);
5732         } else {
5733                 switch (wc) {
5734
5735                 case 10:
5736                         if(pwlen){
5737                                 /* password, ASCII */
5738                                 CHECK_BYTE_COUNT(pwlen);
5739                                 proto_tree_add_item(tree, hf_smb_password,
5740                                         tvb, offset, pwlen, TRUE);
5741                                 COUNT_BYTES(pwlen);
5742                         }
5743
5744                         break;
5745
5746                 case 13:
5747                         if(apwlen){
5748                                 /* password, ANSI */
5749                                 CHECK_BYTE_COUNT(apwlen);
5750                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5751                                         tvb, offset, apwlen, TRUE);
5752                                 COUNT_BYTES(apwlen);
5753                         }
5754
5755                         if(upwlen){
5756                                 proto_item *item;
5757
5758                                 /* password, Unicode */
5759                                 CHECK_BYTE_COUNT(upwlen);
5760                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5761                                         tvb, offset, upwlen, TRUE);
5762
5763                                 if (upwlen > 24) {
5764                                         proto_tree *subtree;
5765
5766                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5767
5768                                         dissect_ntlmv2_response(
5769                                                 tvb, subtree, offset, upwlen);
5770                                 }
5771
5772                                 COUNT_BYTES(upwlen);
5773                         }
5774
5775                         break;
5776                 }
5777
5778                 /* Account Name */
5779                 an = get_unicode_or_ascii_string(tvb, &offset,
5780                         si->unicode, &an_len, FALSE, FALSE, &bc);
5781                 if (an == NULL)
5782                         goto endofcommand;
5783                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5784                         an);
5785                 COUNT_BYTES(an_len);
5786
5787                 /* Primary domain */
5788                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5789                  * byte in front of this, at least if all the strings are
5790                  * ASCII and the account name is empty. Another bug?
5791                  */
5792                 dn = get_unicode_or_ascii_string(tvb, &offset,
5793                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5794                 if (dn == NULL)
5795                         goto endofcommand;
5796                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5797                         offset, dn_len, dn);
5798                 COUNT_BYTES(dn_len);
5799
5800                 if (check_col(pinfo->cinfo, COL_INFO)) {
5801                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5802
5803                         if (!dn[0] && !an[0])
5804                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5805                                                 "anonymous");
5806                         else
5807                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5808                                                 "%s\\%s", dn,an);
5809                 }
5810
5811                 /* OS */
5812                 an = get_unicode_or_ascii_string(tvb, &offset,
5813                         si->unicode, &an_len, FALSE, FALSE, &bc);
5814                 if (an == NULL)
5815                         goto endofcommand;
5816                 proto_tree_add_string(tree, hf_smb_os, tvb,
5817                         offset, an_len, an);
5818                 COUNT_BYTES(an_len);
5819
5820                 /* LANMAN */
5821                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5822                  * padding/null string/whatever in front of this. W2K doesn't
5823                  * appear to. I suspect that's a bug that got fixed; I also
5824                  * suspect that, in practice, nobody ever looks at that field
5825                  * because the bug didn't appear to get fixed until NT 5.0....
5826                  */
5827                 an = get_unicode_or_ascii_string(tvb, &offset,
5828                         si->unicode, &an_len, FALSE, FALSE, &bc);
5829                 if (an == NULL)
5830                         goto endofcommand;
5831                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5832                         offset, an_len, an);
5833                 COUNT_BYTES(an_len);
5834         }
5835
5836         END_OF_SMB
5837
5838         /* call AndXCommand (if there are any) */
5839         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5840
5841         return offset;
5842 }
5843
5844 static int
5845 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5846 {
5847         guint8  wc, cmd=0xff;
5848         guint16 andxoffset=0, bc;
5849         guint16 sbloblen=0;
5850         smb_info_t *si = pinfo->private_data;
5851         int an_len;
5852         const char *an;
5853
5854         WORD_COUNT;
5855
5856         /* next smb command */
5857         cmd = tvb_get_guint8(tvb, offset);
5858         if(cmd!=0xff){
5859                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5860         } else {
5861                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5862         }
5863         offset += 1;
5864
5865         /* reserved byte */
5866         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5867         offset += 1;
5868
5869         /* andxoffset */
5870         andxoffset = tvb_get_letohs(tvb, offset);
5871         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5872         offset += 2;
5873
5874         /* flags */
5875         offset = dissect_setup_action(tvb, tree, offset);
5876
5877         if(wc==4){
5878                 /* security blob length */
5879                 sbloblen = tvb_get_letohs(tvb, offset);
5880                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5881                 offset += 2;
5882         }
5883
5884         BYTE_COUNT;
5885
5886         if(wc==4) {
5887                 proto_item *blob_item;
5888
5889                 /* security blob */
5890
5891                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5892                                                 tvb, offset, sbloblen, TRUE);
5893
5894                 if(sbloblen){
5895                         tvbuff_t *blob_tvb;
5896                         proto_tree *blob_tree;
5897
5898                         blob_tree = proto_item_add_subtree(blob_item, 
5899                                                            ett_smb_secblob);
5900                         CHECK_BYTE_COUNT(sbloblen);
5901
5902                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5903                                                     sbloblen);
5904
5905                         if (si && si->ct && si->ct->raw_ntlmssp && 
5906                             !strncmp("NTLMSSP", 
5907                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5908                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5909                                          blob_tree);
5910
5911                         }
5912                         else {
5913                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
5914                                          blob_tree);
5915
5916                         }
5917
5918                         COUNT_BYTES(sbloblen);
5919                 }
5920         }
5921
5922         /* OS */
5923         an = get_unicode_or_ascii_string(tvb, &offset,
5924                 si->unicode, &an_len, FALSE, FALSE, &bc);
5925         if (an == NULL)
5926                 goto endofcommand;
5927         proto_tree_add_string(tree, hf_smb_os, tvb,
5928                 offset, an_len, an);
5929         COUNT_BYTES(an_len);
5930
5931         /* LANMAN */
5932         an = get_unicode_or_ascii_string(tvb, &offset,
5933                 si->unicode, &an_len, FALSE, FALSE, &bc);
5934         if (an == NULL)
5935                 goto endofcommand;
5936         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5937                 offset, an_len, an);
5938         COUNT_BYTES(an_len);
5939
5940         if(wc==3) {
5941                 /* Primary domain */
5942                 an = get_unicode_or_ascii_string(tvb, &offset,
5943                         si->unicode, &an_len, FALSE, FALSE, &bc);
5944                 if (an == NULL)
5945                         goto endofcommand;
5946                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5947                         offset, an_len, an);
5948                 COUNT_BYTES(an_len);
5949         }
5950
5951         END_OF_SMB
5952
5953         /* call AndXCommand (if there are any) */
5954         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5955
5956         return offset;
5957 }
5958
5959
5960 static int
5961 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5962 {
5963         guint8  wc, cmd=0xff;
5964         guint16 andxoffset=0;
5965         guint16 bc;
5966
5967         WORD_COUNT;
5968
5969         /* next smb command */
5970         cmd = tvb_get_guint8(tvb, offset);
5971         if(cmd!=0xff){
5972                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5973         } else {
5974                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5975         }
5976         offset += 1;
5977
5978         /* reserved byte */
5979         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5980         offset += 1;
5981
5982         /* andxoffset */
5983         andxoffset = tvb_get_letohs(tvb, offset);
5984         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5985         offset += 2;
5986
5987         BYTE_COUNT;
5988
5989         END_OF_SMB
5990
5991         /* call AndXCommand (if there are any) */
5992         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5993
5994         return offset;
5995 }
5996
5997
5998 static const true_false_string tfs_connect_support_search = {
5999         "Exclusive search bits supported",
6000         "Exclusive search bits not supported"
6001 };
6002 static const true_false_string tfs_connect_support_in_dfs = {
6003         "Share is in Dfs",
6004         "Share isn't in Dfs"
6005 };
6006
6007 static int
6008 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6009 {
6010         guint16 mask;
6011         proto_item *item = NULL;
6012         proto_tree *tree = NULL;
6013
6014         mask = tvb_get_letohs(tvb, offset);
6015
6016         if(parent_tree){
6017                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6018                         "Optional Support: 0x%04x", mask);
6019                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6020         }
6021
6022         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6023                 tvb, offset, 2, mask);
6024         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6025                 tvb, offset, 2, mask);
6026
6027         offset += 2;
6028
6029         return offset;
6030 }
6031
6032 static const true_false_string tfs_disconnect_tid = {
6033         "DISCONNECT TID",
6034         "Do NOT disconnect TID"
6035 };
6036
6037 static int
6038 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6039 {
6040         guint16 mask;
6041         proto_item *item = NULL;
6042         proto_tree *tree = NULL;
6043
6044         mask = tvb_get_letohs(tvb, offset);
6045
6046         if(parent_tree){
6047                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6048                         "Flags: 0x%04x", mask);
6049                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6050         }
6051
6052         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6053                 tvb, offset, 2, mask);
6054
6055         offset += 2;
6056
6057         return offset;
6058 }
6059
6060 static int
6061 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6062 {
6063         guint8  wc, cmd=0xff;
6064         guint16 bc;
6065         guint16 andxoffset=0, pwlen=0;
6066         smb_info_t *si = pinfo->private_data;
6067         int an_len;
6068         const char *an;
6069
6070         WORD_COUNT;
6071
6072         /* next smb command */
6073         cmd = tvb_get_guint8(tvb, offset);
6074         if(cmd!=0xff){
6075                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6076         } else {
6077                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6078         }
6079         offset += 1;
6080
6081         /* reserved byte */
6082         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6083         offset += 1;
6084
6085         /* andxoffset */
6086         andxoffset = tvb_get_letohs(tvb, offset);
6087         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6088         offset += 2;
6089
6090         /* flags */
6091         offset = dissect_connect_flags(tvb, tree, offset);
6092
6093         /* password length*/
6094         pwlen = tvb_get_letohs(tvb, offset);
6095         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6096         offset += 2;
6097
6098         BYTE_COUNT;
6099
6100         /* password */
6101         CHECK_BYTE_COUNT(pwlen);
6102         proto_tree_add_item(tree, hf_smb_password,
6103                 tvb, offset, pwlen, TRUE);
6104         COUNT_BYTES(pwlen);
6105
6106         /* Path */
6107         an = get_unicode_or_ascii_string(tvb, &offset,
6108                 si->unicode, &an_len, FALSE, FALSE, &bc);
6109         if (an == NULL)
6110                 goto endofcommand;
6111         proto_tree_add_string(tree, hf_smb_path, tvb,
6112                 offset, an_len, an);
6113         COUNT_BYTES(an_len);
6114
6115         if (check_col(pinfo->cinfo, COL_INFO)) {
6116                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6117         }
6118
6119         /*
6120          * NOTE: the Service string is always ASCII, even if the
6121          * "strings are Unicode" bit is set in the flags2 field
6122          * of the SMB.
6123          */
6124
6125         /* Service */
6126         /* XXX - what if this runs past bc? */
6127         an_len = tvb_strsize(tvb, offset);
6128         CHECK_BYTE_COUNT(an_len);
6129         an = tvb_get_ptr(tvb, offset, an_len);
6130         proto_tree_add_string(tree, hf_smb_service, tvb,
6131                 offset, an_len, an);
6132         COUNT_BYTES(an_len);
6133
6134         END_OF_SMB
6135
6136         /* call AndXCommand (if there are any) */
6137         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6138
6139         return offset;
6140 }
6141
6142
6143 static int
6144 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6145 {
6146         guint8  wc, wleft, cmd=0xff;
6147         guint16 andxoffset=0;
6148         guint16 bc;
6149         int an_len;
6150         const char *an;
6151         smb_info_t *si = pinfo->private_data;
6152
6153         WORD_COUNT;
6154
6155         wleft = wc;     /* this is at least 1 */
6156
6157         /* next smb command */
6158         cmd = tvb_get_guint8(tvb, offset);
6159         if(cmd!=0xff){
6160                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6161         } else {
6162                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6163         }
6164         offset += 1;
6165
6166         /* reserved byte */
6167         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6168         offset += 1;
6169
6170         wleft--;
6171         if (wleft == 0)
6172                 goto bytecount;
6173
6174         /* andxoffset */
6175         andxoffset = tvb_get_letohs(tvb, offset);
6176         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6177         offset += 2;
6178         wleft--;
6179         if (wleft == 0)
6180                 goto bytecount;
6181
6182         /* flags */
6183         offset = dissect_connect_support_bits(tvb, tree, offset);
6184         wleft--;
6185
6186         /* XXX - I've seen captures where this is 7, but I have no
6187            idea how to dissect it.  I'm guessing the third word
6188            contains connect support bits, which looks plausible
6189            from the values I've seen. */
6190
6191         while (wleft != 0) {
6192                 proto_tree_add_text(tree, tvb, offset, 2,
6193                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6194                 offset += 2;
6195                 wleft--;
6196         }
6197
6198         BYTE_COUNT;
6199
6200         /*
6201          * NOTE: even though the SNIA CIFS spec doesn't say there's
6202          * a "Service" string if there's a word count of 2, the
6203          * document at
6204          *
6205          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6206          *
6207          * (it's in an ugly format - text intended to be sent to a
6208          * printer, with backspaces and overstrikes used for boldfacing
6209          * and underlining; UNIX "col -b" can be used to strip the
6210          * overstrikes out) says there's a "Service" string there, and
6211          * some network traffic has it.
6212          */
6213
6214         /*
6215          * NOTE: the Service string is always ASCII, even if the
6216          * "strings are Unicode" bit is set in the flags2 field
6217          * of the SMB.
6218          */
6219
6220         /* Service */
6221         /* XXX - what if this runs past bc? */
6222         an_len = tvb_strsize(tvb, offset);
6223         CHECK_BYTE_COUNT(an_len);
6224         an = tvb_get_ptr(tvb, offset, an_len);
6225         proto_tree_add_string(tree, hf_smb_service, tvb,
6226                 offset, an_len, an);
6227         COUNT_BYTES(an_len);
6228
6229         /* Now when we know the service type, store it so that we know it for later commands down
6230            this tree */
6231         if(!pinfo->fd->flags.visited){
6232                 /* Remove any previous entry for this TID */
6233                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6234                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6235                 }
6236                 if(strcmp(an,"IPC") == 0){
6237                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6238                 } else {
6239                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6240                 }
6241         }
6242
6243
6244         if(wc==3){
6245                 if (bc != 0) {
6246                         /*
6247                          * Sometimes this isn't present.
6248                          */
6249
6250                         /* Native FS */
6251                         an = get_unicode_or_ascii_string(tvb, &offset,
6252                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6253                                 &bc);
6254                         if (an == NULL)
6255                                 goto endofcommand;
6256                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6257                                 offset, an_len, an);
6258                         COUNT_BYTES(an_len);
6259                 }
6260         }
6261
6262         END_OF_SMB
6263
6264         /* call AndXCommand (if there are any) */
6265         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6266
6267         return offset;
6268 }
6269
6270
6271
6272 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6273    NT Transaction command  begins here
6274    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6275 #define NT_TRANS_CREATE         1
6276 #define NT_TRANS_IOCTL          2
6277 #define NT_TRANS_SSD            3
6278 #define NT_TRANS_NOTIFY         4
6279 #define NT_TRANS_RENAME         5
6280 #define NT_TRANS_QSD            6
6281 #define NT_TRANS_GET_USER_QUOTA 7
6282 #define NT_TRANS_SET_USER_QUOTA 8
6283 const value_string nt_cmd_vals[] = {
6284         {NT_TRANS_CREATE,               "NT CREATE"},
6285         {NT_TRANS_IOCTL,                "NT IOCTL"},
6286         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6287         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6288         {NT_TRANS_RENAME,               "NT RENAME"},
6289         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6290         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6291         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6292         {0, NULL}
6293 };
6294
6295 static const value_string nt_ioctl_isfsctl_vals[] = {
6296         {0,     "Device IOCTL"},
6297         {1,     "FS control : FSCTL"},
6298         {0, NULL}
6299 };
6300
6301 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6302 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6303         "Apply the command to share root handle (MUST BE Dfs)",
6304         "Apply to this share",
6305 };
6306
6307 static const value_string nt_notify_action_vals[] = {
6308         {1,     "ADDED (object was added"},
6309         {2,     "REMOVED (object was removed)"},
6310         {3,     "MODIFIED (object was modified)"},
6311         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6312         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6313         {6,     "ADDED_STREAM (a stream was added)"},
6314         {7,     "REMOVED_STREAM (a stream was removed)"},
6315         {8,     "MODIFIED_STREAM (a stream was modified)"},
6316         {0, NULL}
6317 };
6318
6319 static const value_string watch_tree_vals[] = {
6320         {0,     "Current directory only"},
6321         {1,     "Subdirectories also"},
6322         {0, NULL}
6323 };
6324
6325 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6326 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6327 #define NT_NOTIFY_STREAM_NAME   0x00000200
6328 #define NT_NOTIFY_SECURITY      0x00000100
6329 #define NT_NOTIFY_EA            0x00000080
6330 #define NT_NOTIFY_CREATION      0x00000040
6331 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6332 #define NT_NOTIFY_LAST_WRITE    0x00000010
6333 #define NT_NOTIFY_SIZE          0x00000008
6334 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6335 #define NT_NOTIFY_DIR_NAME      0x00000002
6336 #define NT_NOTIFY_FILE_NAME     0x00000001
6337 static const true_false_string tfs_nt_notify_stream_write = {
6338         "Notify on changes to STREAM WRITE",
6339         "Do NOT notify on changes to stream write",
6340 };
6341 static const true_false_string tfs_nt_notify_stream_size = {
6342         "Notify on changes to STREAM SIZE",
6343         "Do NOT notify on changes to stream size",
6344 };
6345 static const true_false_string tfs_nt_notify_stream_name = {
6346         "Notify on changes to STREAM NAME",
6347         "Do NOT notify on changes to stream name",
6348 };
6349 static const true_false_string tfs_nt_notify_security = {
6350         "Notify on changes to SECURITY",
6351         "Do NOT notify on changes to security",
6352 };
6353 static const true_false_string tfs_nt_notify_ea = {
6354         "Notify on changes to EA",
6355         "Do NOT notify on changes to EA",
6356 };
6357 static const true_false_string tfs_nt_notify_creation = {
6358         "Notify on changes to CREATION TIME",
6359         "Do NOT notify on changes to creation time",
6360 };
6361 static const true_false_string tfs_nt_notify_last_access = {
6362         "Notify on changes to LAST ACCESS TIME",
6363         "Do NOT notify on changes to last access time",
6364 };
6365 static const true_false_string tfs_nt_notify_last_write = {
6366         "Notify on changes to LAST WRITE TIME",
6367         "Do NOT notify on changes to last write time",
6368 };
6369 static const true_false_string tfs_nt_notify_size = {
6370         "Notify on changes to SIZE",
6371         "Do NOT notify on changes to size",
6372 };
6373 static const true_false_string tfs_nt_notify_attributes = {
6374         "Notify on changes to ATTRIBUTES",
6375         "Do NOT notify on changes to attributes",
6376 };
6377 static const true_false_string tfs_nt_notify_dir_name = {
6378         "Notify on changes to DIR NAME",
6379         "Do NOT notify on changes to dir name",
6380 };
6381 static const true_false_string tfs_nt_notify_file_name = {
6382         "Notify on changes to FILE NAME",
6383         "Do NOT notify on changes to file name",
6384 };
6385
6386 static const value_string create_disposition_vals[] = {
6387         {0,     "Supersede (supersede existing file (if it exists))"},
6388         {1,     "Open (if file exists open it, else fail)"},
6389         {2,     "Create (if file exists fail, else create it)"},
6390         {3,     "Open If (if file exists open it, else create it)"},
6391         {4,     "Overwrite (if file exists overwrite, else fail)"},
6392         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6393         {0, NULL}
6394 };
6395
6396 static const value_string impersonation_level_vals[] = {
6397         {0,     "Anonymous"},
6398         {1,     "Identification"},
6399         {2,     "Impersonation"},
6400         {3,     "Delegation"},
6401         {0, NULL}
6402 };
6403
6404 static const true_false_string tfs_nt_security_flags_context_tracking = {
6405         "Security tracking mode is DYNAMIC",
6406         "Security tracking mode is STATIC",
6407 };
6408
6409 static const true_false_string tfs_nt_security_flags_effective_only = {
6410         "ONLY ENABLED aspects of the client's security context are available",
6411         "ALL aspects of the client's security context are available",
6412 };
6413
6414 static const true_false_string tfs_nt_create_bits_oplock = {
6415         "Requesting OPLOCK",
6416         "Does NOT request oplock"
6417 };
6418
6419 static const true_false_string tfs_nt_create_bits_boplock = {
6420         "Requesting BATCH OPLOCK",
6421         "Does NOT request batch oplock"
6422 };
6423
6424 /*
6425  * XXX - must be a directory, and can be a file, or can be a directory,
6426  * and must be a file?
6427  */
6428 static const true_false_string tfs_nt_create_bits_dir = {
6429         "Target of open MUST be a DIRECTORY",
6430         "Target of open can be a file"
6431 };
6432
6433 static const true_false_string tfs_nt_create_bits_ext_resp = {
6434   "Extended responses required",
6435   "Extended responses NOT required"
6436 };
6437
6438 static const true_false_string tfs_nt_access_mask_generic_read = {
6439         "GENERIC READ is set",
6440         "Generic read is NOT set"
6441 };
6442 static const true_false_string tfs_nt_access_mask_generic_write = {
6443         "GENERIC WRITE is set",
6444         "Generic write is NOT set"
6445 };
6446 static const true_false_string tfs_nt_access_mask_generic_execute = {
6447         "GENERIC EXECUTE is set",
6448         "Generic execute is NOT set"
6449 };
6450 static const true_false_string tfs_nt_access_mask_generic_all = {
6451         "GENERIC ALL is set",
6452         "Generic all is NOT set"
6453 };
6454 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6455         "MAXIMUM ALLOWED is set",
6456         "Maximum allowed is NOT set"
6457 };
6458 static const true_false_string tfs_nt_access_mask_system_security = {
6459         "SYSTEM SECURITY is set",
6460         "System security is NOT set"
6461 };
6462 static const true_false_string tfs_nt_access_mask_synchronize = {
6463         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6464         "Can NOT wait on handle to synchronize on completion of I/O"
6465 };
6466 static const true_false_string tfs_nt_access_mask_write_owner = {
6467         "Can WRITE OWNER (take ownership)",
6468         "Can NOT write owner (take ownership)"
6469 };
6470 static const true_false_string tfs_nt_access_mask_write_dac = {
6471         "OWNER may WRITE the DAC",
6472         "Owner may NOT write to the DAC"
6473 };
6474 static const true_false_string tfs_nt_access_mask_read_control = {
6475         "READ ACCESS to owner, group and ACL of the SID",
6476         "Read access is NOT granted to owner, group and ACL of the SID"
6477 };
6478 static const true_false_string tfs_nt_access_mask_delete = {
6479         "DELETE access",
6480         "NO delete access"
6481 };
6482 static const true_false_string tfs_nt_access_mask_write_attributes = {
6483         "WRITE ATTRIBUTES access",
6484         "NO write attributes access"
6485 };
6486 static const true_false_string tfs_nt_access_mask_read_attributes = {
6487         "READ ATTRIBUTES access",
6488         "NO read attributes access"
6489 };
6490 static const true_false_string tfs_nt_access_mask_delete_child = {
6491         "DELETE CHILD access",
6492         "NO delete child access"
6493 };
6494 static const true_false_string tfs_nt_access_mask_execute = {
6495         "EXECUTE access",
6496         "NO execute access"
6497 };
6498 static const true_false_string tfs_nt_access_mask_write_ea = {
6499         "WRITE EXTENDED ATTRIBUTES access",
6500         "NO write extended attributes access"
6501 };
6502 static const true_false_string tfs_nt_access_mask_read_ea = {
6503         "READ EXTENDED ATTRIBUTES access",
6504         "NO read extended attributes access"
6505 };
6506 static const true_false_string tfs_nt_access_mask_append = {
6507         "APPEND access",
6508         "NO append access"
6509 };
6510 static const true_false_string tfs_nt_access_mask_write = {
6511         "WRITE access",
6512         "NO write access"
6513 };
6514 static const true_false_string tfs_nt_access_mask_read = {
6515         "READ access",
6516         "NO read access"
6517 };
6518
6519 static const true_false_string tfs_nt_share_access_delete = {
6520         "Object can be shared for DELETE",
6521         "Object can NOT be shared for delete"
6522 };
6523 static const true_false_string tfs_nt_share_access_write = {
6524         "Object can be shared for WRITE",
6525         "Object can NOT be shared for write"
6526 };
6527 static const true_false_string tfs_nt_share_access_read = {
6528         "Object can be shared for READ",
6529         "Object can NOT be shared for read"
6530 };
6531
6532 static const value_string oplock_level_vals[] = {
6533         {0,     "No oplock granted"},
6534         {1,     "Exclusive oplock granted"},
6535         {2,     "Batch oplock granted"},
6536         {3,     "Level II oplock granted"},
6537         {0, NULL}
6538 };
6539
6540 static const value_string device_type_vals[] = {
6541         {0x00000001,    "Beep"},
6542         {0x00000002,    "CDROM"},
6543         {0x00000003,    "CDROM Filesystem"},
6544         {0x00000004,    "Controller"},
6545         {0x00000005,    "Datalink"},
6546         {0x00000006,    "Dfs"},
6547         {0x00000007,    "Disk"},
6548         {0x00000008,    "Disk Filesystem"},
6549         {0x00000009,    "Filesystem"},
6550         {0x0000000a,    "Inport Port"},
6551         {0x0000000b,    "Keyboard"},
6552         {0x0000000c,    "Mailslot"},
6553         {0x0000000d,    "MIDI-In"},
6554         {0x0000000e,    "MIDI-Out"},
6555         {0x0000000f,    "Mouse"},
6556         {0x00000010,    "Multi UNC Provider"},
6557         {0x00000011,    "Named Pipe"},
6558         {0x00000012,    "Network"},
6559         {0x00000013,    "Network Browser"},
6560         {0x00000014,    "Network Filesystem"},
6561         {0x00000015,    "NULL"},
6562         {0x00000016,    "Parallel Port"},
6563         {0x00000017,    "Physical card"},
6564         {0x00000018,    "Printer"},
6565         {0x00000019,    "Scanner"},
6566         {0x0000001a,    "Serial Mouse port"},
6567         {0x0000001b,    "Serial port"},
6568         {0x0000001c,    "Screen"},
6569         {0x0000001d,    "Sound"},
6570         {0x0000001e,    "Streams"},
6571         {0x0000001f,    "Tape"},
6572         {0x00000020,    "Tape Filesystem"},
6573         {0x00000021,    "Transport"},
6574         {0x00000022,    "Unknown"},
6575         {0x00000023,    "Video"},
6576         {0x00000024,    "Virtual Disk"},
6577         {0x00000025,    "WAVE-In"},
6578         {0x00000026,    "WAVE-Out"},
6579         {0x00000027,    "8042 Port"},
6580         {0x00000028,    "Network Redirector"},
6581         {0x00000029,    "Battery"},
6582         {0x0000002a,    "Bus Extender"},
6583         {0x0000002b,    "Modem"},
6584         {0x0000002c,    "VDM"},
6585         {0,     NULL}
6586 };
6587
6588 static const value_string is_directory_vals[] = {
6589         {0,     "This is NOT a directory"},
6590         {1,     "This is a DIRECTORY"},
6591         {0, NULL}
6592 };
6593
6594 typedef struct _nt_trans_data {
6595         int subcmd;
6596         guint32 sd_len;
6597         guint32 ea_len;
6598 } nt_trans_data;
6599
6600
6601
6602 static int
6603 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6604 {
6605         guint8 mask;
6606         proto_item *item = NULL;
6607         proto_tree *tree = NULL;
6608
6609         mask = tvb_get_guint8(tvb, offset);
6610
6611         if(parent_tree){
6612                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6613                         "Security Flags: 0x%02x", mask);
6614                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6615         }
6616
6617         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6618                 tvb, offset, 1, mask);
6619         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6620                 tvb, offset, 1, mask);
6621
6622         offset += 1;
6623
6624         return offset;
6625 }
6626
6627 static int
6628 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6629 {
6630         guint32 mask;
6631         proto_item *item = NULL;
6632         proto_tree *tree = NULL;
6633
6634         mask = tvb_get_letohl(tvb, offset);
6635
6636         if(parent_tree){
6637                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6638                         "Share Access: 0x%08x", mask);
6639                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6640         }
6641
6642         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6643                 tvb, offset, 4, mask);
6644         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6645                 tvb, offset, 4, mask);
6646         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6647                 tvb, offset, 4, mask);
6648
6649         offset += 4;
6650
6651         return offset;
6652 }
6653
6654 /* FIXME: need to call dissect_nt_access_mask() instead */
6655
6656 static int
6657 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6658 {
6659         guint32 mask;
6660         proto_item *item = NULL;
6661         proto_tree *tree = NULL;
6662
6663         mask = tvb_get_letohl(tvb, offset);
6664
6665         if(parent_tree){
6666                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6667                         "Access Mask: 0x%08x", mask);
6668                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6669         }
6670
6671         /*
6672          * Some of these bits come from
6673          *
6674          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6675          *
6676          * and others come from the section on ZwOpenFile in "Windows(R)
6677          * NT(R)/2000 Native API Reference".
6678          */
6679         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6680                 tvb, offset, 4, mask);
6681         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6682                 tvb, offset, 4, mask);
6683         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6684                 tvb, offset, 4, mask);
6685         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6686                 tvb, offset, 4, mask);
6687         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6688                 tvb, offset, 4, mask);
6689         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6690                 tvb, offset, 4, mask);
6691         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6692                 tvb, offset, 4, mask);
6693         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6694                 tvb, offset, 4, mask);
6695         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6696                 tvb, offset, 4, mask);
6697         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6698                 tvb, offset, 4, mask);
6699         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6700                 tvb, offset, 4, mask);
6701         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6702                 tvb, offset, 4, mask);
6703         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6704                 tvb, offset, 4, mask);
6705         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6706                 tvb, offset, 4, mask);
6707         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6708                 tvb, offset, 4, mask);
6709         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6710                 tvb, offset, 4, mask);
6711         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6712                 tvb, offset, 4, mask);
6713         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6714                 tvb, offset, 4, mask);
6715         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6716                 tvb, offset, 4, mask);
6717         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6718                 tvb, offset, 4, mask);
6719
6720         offset += 4;
6721
6722         return offset;
6723 }
6724
6725 static int
6726 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6727 {
6728         guint32 mask;
6729         proto_item *item = NULL;
6730         proto_tree *tree = NULL;
6731
6732         mask = tvb_get_letohl(tvb, offset);
6733
6734         if(parent_tree){
6735                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6736                         "Create Flags: 0x%08x", mask);
6737                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6738         }
6739
6740         /*
6741          * XXX - it's 0x00000016 in at least one capture, but
6742          * Network Monitor doesn't say what the 0x00000010 bit is.
6743          * Does the Win32 API documentation, or NT Native API book,
6744          * suggest anything?
6745          *
6746          * That is the extended response desired bit ... RJS, from Samba
6747          * Well, maybe. Samba thinks it is, and uses it to encode
6748          * OpLock granted as the high order bit of the Action field
6749          * in the response. However, Windows does not do that. Or at least
6750          * Win2K doesn't.
6751          */
6752         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6753                                tvb, offset, 4, mask);
6754         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6755                 tvb, offset, 4, mask);
6756         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6757                 tvb, offset, 4, mask);
6758         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6759                 tvb, offset, 4, mask);
6760
6761         offset += 4;
6762
6763         return offset;
6764 }
6765
6766 /*
6767  * XXX - there are some more flags in the description of "ZwOpenFile()"
6768  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6769  * the wire as well?  (The spec at
6770  *
6771  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6772  *
6773  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6774  * via the SMB protocol.  The NT redirector should convert this option
6775  * to FILE_WRITE_THROUGH."
6776  *
6777  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6778  * values one would infer from their position in the list of flags for
6779  * "ZwOpenFile()".  Most of the others probably have those values
6780  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6781  * which might go over the wire (for the benefit of backup/restore software).
6782  */
6783 static const true_false_string tfs_nt_create_options_directory = {
6784         "File being created/opened must be a directory",
6785         "File being created/opened must not be a directory"
6786 };
6787 static const true_false_string tfs_nt_create_options_write_through = {
6788         "Writes should flush buffered data before completing",
6789         "Writes need not flush buffered data before completing"
6790 };
6791 static const true_false_string tfs_nt_create_options_sequential_only = {
6792         "The file will only be accessed sequentially",
6793         "The file might not only be accessed sequentially"
6794 };
6795 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6796         "All operations SYNCHRONOUS, waits subject to termination from alert",
6797         "Operations NOT necessarily synchronous"
6798 };
6799 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6800         "All operations SYNCHRONOUS, waits not subject to alert",
6801         "Operations NOT necessarily synchronous"
6802 };
6803 static const true_false_string tfs_nt_create_options_non_directory = {
6804         "File being created/opened must not be a directory",
6805         "File being created/opened must be a directory"
6806 };
6807 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6808         "The client does not understand extended attributes",
6809         "The client understands extended attributes"
6810 };
6811 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6812         "The client understands only 8.3 file names",
6813         "The client understands long file names"
6814 };
6815 static const true_false_string tfs_nt_create_options_random_access = {
6816         "The file will be accessed randomly",
6817         "The file will not be accessed randomly"
6818 };
6819 static const true_false_string tfs_nt_create_options_delete_on_close = {
6820         "The file should be deleted when it is closed",
6821         "The file should not be deleted when it is closed"
6822 };
6823
6824 static int
6825 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6826 {
6827         guint32 mask;
6828         proto_item *item = NULL;
6829         proto_tree *tree = NULL;
6830
6831         mask = tvb_get_letohl(tvb, offset);
6832
6833         if(parent_tree){
6834                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6835                         "Create Options: 0x%08x", mask);
6836                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6837         }
6838
6839         /*
6840          * From
6841          *
6842          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6843          */
6844         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6855                 tvb, offset, 4, mask);
6856         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6857                 tvb, offset, 4, mask);
6858         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6859                 tvb, offset, 4, mask);
6860         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6861                 tvb, offset, 4, mask);
6862         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6863                 tvb, offset, 4, mask);
6864
6865         offset += 4;
6866
6867         return offset;
6868 }
6869
6870 static int
6871 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6872 {
6873         guint32 mask;
6874         proto_item *item = NULL;
6875         proto_tree *tree = NULL;
6876
6877         mask = tvb_get_letohl(tvb, offset);
6878
6879         if(parent_tree){
6880                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6881                         "Completion Filter: 0x%08x", mask);
6882                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6883         }
6884
6885         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6886                 tvb, offset, 4, mask);
6887         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6888                 tvb, offset, 4, mask);
6889         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6890                 tvb, offset, 4, mask);
6891         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6892                 tvb, offset, 4, mask);
6893         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6894                 tvb, offset, 4, mask);
6895         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6896                 tvb, offset, 4, mask);
6897         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6898                 tvb, offset, 4, mask);
6899         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6900                 tvb, offset, 4, mask);
6901         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6902                 tvb, offset, 4, mask);
6903         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6904                 tvb, offset, 4, mask);
6905         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6906                 tvb, offset, 4, mask);
6907         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6908                 tvb, offset, 4, mask);
6909
6910         offset += 4;
6911         return offset;
6912 }
6913
6914 static int
6915 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6916 {
6917         guint8 mask;
6918         proto_item *item = NULL;
6919         proto_tree *tree = NULL;
6920
6921         mask = tvb_get_guint8(tvb, offset);
6922
6923         if(parent_tree){
6924                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6925                         "Completion Filter: 0x%02x", mask);
6926                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6927         }
6928
6929         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6930                 tvb, offset, 1, mask);
6931
6932         offset += 1;
6933         return offset;
6934 }
6935
6936 /*
6937  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6938  * Native API Reference".
6939  */
6940 static const true_false_string tfs_nt_qsd_owner = {
6941         "Requesting OWNER security information",
6942         "NOT requesting owner security information",
6943 };
6944
6945 static const true_false_string tfs_nt_qsd_group = {
6946         "Requesting GROUP security information",
6947         "NOT requesting group security information",
6948 };
6949
6950 static const true_false_string tfs_nt_qsd_dacl = {
6951         "Requesting DACL security information",
6952         "NOT requesting DACL security information",
6953 };
6954
6955 static const true_false_string tfs_nt_qsd_sacl = {
6956         "Requesting SACL security information",
6957         "NOT requesting SACL security information",
6958 };
6959
6960 #define NT_QSD_OWNER    0x00000001
6961 #define NT_QSD_GROUP    0x00000002
6962 #define NT_QSD_DACL     0x00000004
6963 #define NT_QSD_SACL     0x00000008
6964
6965 static int
6966 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6967 {
6968         guint32 mask;
6969         proto_item *item = NULL;
6970         proto_tree *tree = NULL;
6971
6972         mask = tvb_get_letohl(tvb, offset);
6973
6974         if(parent_tree){
6975                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6976                         "Security Information: 0x%08x", mask);
6977                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6978         }
6979
6980         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6981                 tvb, offset, 4, mask);
6982         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6983                 tvb, offset, 4, mask);
6984         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6985                 tvb, offset, 4, mask);
6986         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6987                 tvb, offset, 4, mask);
6988
6989         offset += 4;
6990
6991         return offset;
6992 }
6993
6994 static void
6995 free_g_string(void *arg)
6996 {
6997         g_string_free(arg, TRUE);
6998 }
6999
7000 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7001    the SID in the 'sid_str' parameter which must be freed by the caller.
7002    hf_sid can be -1 if the caller doesnt care what name is used and then 
7003    "smb.sid" will be the default instead. If the caller wants a more
7004    appropriate hf field, it will just pass a FT_STRING hf field here
7005 */
7006
7007 int
7008 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7009                char **sid_str, int hf_sid)
7010 {
7011         proto_item *item = NULL;
7012         proto_tree *tree = NULL;
7013         int old_offset = offset, sa_offset = offset;
7014         gboolean rid_present;
7015         guint rid=0;
7016         int rid_offset=0;
7017         guint8 revision;
7018         int rev_offset;
7019         guint8 num_auth;
7020         int na_offset;
7021         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7022         int i;
7023         GString *gstr;
7024         char sid_string[245];
7025         char *sid_name;
7026
7027         if(hf_sid==-1){
7028                 hf_sid=hf_smb_sid;
7029         }
7030
7031         /* revision of sid */
7032         revision = tvb_get_guint8(tvb, offset);
7033         rev_offset = offset;
7034         offset += 1;
7035
7036         switch(revision){
7037         case 1:
7038         case 2:  /* Not sure what the different revision numbers mean */
7039           /* number of authorities*/
7040           num_auth = tvb_get_guint8(tvb, offset);
7041           na_offset = offset;
7042           offset += 1;
7043
7044           /* XXX perhaps we should have these thing searchable?
7045              a new FT_xxx thingie? SMB is quite common!*/
7046           /* identifier authorities */
7047
7048           for(i=0;i<6;i++){
7049             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7050
7051             offset++;
7052           }
7053
7054           sa_offset = offset;
7055
7056           gstr = g_string_new("");
7057
7058           CLEANUP_PUSH(free_g_string, gstr);
7059
7060           /* sub authorities, leave RID to last */
7061           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7062             /*
7063              * XXX should not be letohl but native byteorder according to
7064              * Samba header files.
7065              *
7066              * However, considering that there were never any NT ports
7067              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7068              * and IA-64 runs little-endian, as does x86-64), we can (?)
7069              * assume that non le byte encodings will be "uncommon"?
7070              */
7071              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7072                   tvb_get_letohl(tvb, offset));
7073              offset+=4;
7074           }
7075
7076
7077           if (num_auth > 4) {
7078             rid = tvb_get_letohl(tvb, offset);
7079             rid_present=TRUE;
7080             rid_offset=offset;
7081             offset+=4;
7082             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7083           } else {
7084             rid_present=FALSE;
7085             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7086           }
7087
7088           sid_name=NULL;
7089           if(sid_name_snooping){
7090             sid_name=find_sid_name(sid_string);
7091           }
7092
7093           if(parent_tree){
7094             if(sid_name){
7095               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s (%s)", name, sid_string, sid_name);
7096             } else {
7097               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7098             }
7099             tree = proto_item_add_subtree(item, ett_smb_sid);
7100           }
7101
7102           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7103           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7104           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7105           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7106
7107           if(rid_present){
7108             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7109           }
7110
7111           if(sid_str){
7112             if(sid_name){
7113               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7114             } else {
7115               *sid_str = g_strdup(sid_string);
7116             }
7117           }
7118
7119           CLEANUP_CALL_AND_POP;
7120         }
7121
7122
7123         return offset;
7124 }
7125
7126
7127 static const value_string ace_type_vals[] = {
7128   { 0, "Access Allowed"},
7129   { 1, "Access Denied"},
7130   { 2, "System Audit"},
7131   { 3, "System Alarm"},
7132   { 0, NULL}
7133 };
7134 static const true_false_string tfs_ace_flags_object_inherit = {
7135   "Subordinate files will inherit this ACE",
7136   "Subordinate files will not inherit this ACE"
7137 };
7138 static const true_false_string tfs_ace_flags_container_inherit = {
7139   "Subordinate containers will inherit this ACE",
7140   "Subordinate containers will not inherit this ACE"
7141 };
7142 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7143   "Subordinate object will not propagate the inherited ACE further",
7144   "Subordinate object will propagate the inherited ACE further"
7145 };
7146 static const true_false_string tfs_ace_flags_inherit_only = {
7147   "This ACE does not apply to the current object",
7148   "This ACE applies to the current object"
7149 };
7150 static const true_false_string tfs_ace_flags_inherited_ace = {
7151   "This ACE was inherited from its parent object",
7152   "This ACE was not inherited from its parent object"
7153 };
7154 static const true_false_string tfs_ace_flags_successful_access = {
7155   "Successful accesses will be audited",
7156   "Successful accesses will not be audited"
7157 };
7158 static const true_false_string tfs_ace_flags_failed_access = {
7159   "Failed accesses will be audited",
7160   "Failed accesses will not be audited"
7161 };
7162
7163 #define APPEND_ACE_TEXT(flag, item, string) \
7164         if(flag){                                                       \
7165                 if(item)                                                \
7166                         proto_item_append_text(item, string, sep);      \
7167                 sep = ", ";                                             \
7168         }
7169
7170 static int
7171 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7172                         guint8 *data)
7173 {
7174         proto_item *item = NULL;
7175         proto_tree *tree = NULL;
7176         guint8 mask;
7177         char *sep = " ";
7178
7179         mask = tvb_get_guint8(tvb, offset);
7180
7181         if (data)
7182                 *data = mask;
7183
7184
7185         if(parent_tree){
7186                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7187                                            "NT ACE Flags: 0x%02x", mask);
7188                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7189         }
7190
7191         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7192                        tvb, offset, 1, mask);
7193         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7194
7195         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7196                        tvb, offset, 1, mask);
7197         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7198
7199         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7200                        tvb, offset, 1, mask);
7201         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7202
7203         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7204                        tvb, offset, 1, mask);
7205         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7206
7207         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7208                        tvb, offset, 1, mask);
7209         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7210
7211         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7212                        tvb, offset, 1, mask);
7213         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7214
7215         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7216                        tvb, offset, 1, mask);
7217         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7218
7219
7220         offset += 1;
7221         return offset;
7222 }
7223
7224 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7225
7226 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7227
7228 */
7229
7230 static gint ett_nt_access_mask = -1;
7231 static gint ett_nt_access_mask_generic = -1;
7232 static gint ett_nt_access_mask_standard = -1;
7233 static gint ett_nt_access_mask_specific = -1;
7234
7235 static int hf_access_sacl = -1;
7236 static int hf_access_maximum_allowed = -1;
7237 static int hf_access_generic_read = -1;
7238 static int hf_access_generic_write = -1;
7239 static int hf_access_generic_execute = -1;
7240 static int hf_access_generic_all = -1;
7241 static int hf_access_standard_delete = -1;
7242 static int hf_access_standard_read_control = -1;
7243 static int hf_access_standard_synchronise = -1;
7244 static int hf_access_standard_write_dac = -1;
7245 static int hf_access_standard_write_owner = -1;
7246 static int hf_access_specific_15 = -1;
7247 static int hf_access_specific_14 = -1;
7248 static int hf_access_specific_13 = -1;
7249 static int hf_access_specific_12 = -1;
7250 static int hf_access_specific_11 = -1;
7251 static int hf_access_specific_10 = -1;
7252 static int hf_access_specific_9 = -1;
7253 static int hf_access_specific_8 = -1;
7254 static int hf_access_specific_7 = -1;
7255 static int hf_access_specific_6 = -1;
7256 static int hf_access_specific_5 = -1;
7257 static int hf_access_specific_4 = -1;
7258 static int hf_access_specific_3 = -1;
7259 static int hf_access_specific_2 = -1;
7260 static int hf_access_specific_1 = -1;
7261 static int hf_access_specific_0 = -1;
7262
7263 /* Map generic permissions to specific permissions */
7264
7265 static void map_generic_access(guint32 *access_mask, 
7266                                struct generic_mapping *mapping)
7267 {
7268         if (*access_mask & GENERIC_READ_ACCESS) {
7269                 *access_mask &= ~GENERIC_READ_ACCESS;
7270                 *access_mask |= mapping->generic_read;
7271         }
7272
7273         if (*access_mask & GENERIC_WRITE_ACCESS) {
7274                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7275                 *access_mask |= mapping->generic_write;
7276         }
7277
7278         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7279                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7280                 *access_mask |= mapping->generic_execute;
7281         }
7282
7283         if (*access_mask & GENERIC_ALL_ACCESS) {
7284                 *access_mask &= ~GENERIC_ALL_ACCESS;
7285                 *access_mask |= mapping->generic_all;
7286         }
7287 }
7288
7289 /* Map standard permissions to specific permissions */
7290
7291 static void map_standard_access(guint32 *access_mask,
7292                                 struct standard_mapping *mapping)
7293 {
7294         if (*access_mask & READ_CONTROL_ACCESS) {
7295                 *access_mask &= ~READ_CONTROL_ACCESS;
7296                 *access_mask |= mapping->std_read;
7297         }
7298
7299         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7300                             SYNCHRONIZE_ACCESS)) {
7301                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7302                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7303                 *access_mask |= mapping->std_all;
7304         }
7305
7306 }
7307
7308 int
7309 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7310                        proto_tree *tree, char *drep, int hfindex,
7311                        struct access_mask_info *ami)
7312 {
7313         proto_item *item;
7314         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7315         guint32 access;
7316
7317         if (drep != NULL) {
7318                 /*
7319                  * Called from a DCE RPC protocol dissector, for a
7320                  * protocol where a 32-bit NDR integer contains
7321                  * an NT access mask; extract the access mask
7322                  * with an NDR call.
7323                  */
7324                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7325                                             hfindex, &access);
7326         } else {
7327                 /*
7328                  * Called from SMB, where the access mask is just a
7329                  * 4-byte little-endian quantity with no special
7330                  * NDR alignment requirement; extract it with
7331                  * "tvb_get_letohl()".
7332                  */
7333                 access = tvb_get_letohl(tvb, offset);
7334                 offset += 4;
7335         }
7336
7337         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7338
7339         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7340
7341         /* Generic access rights */
7342
7343         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7344                                    "Generic rights: 0x%08x",
7345                                    access & GENERIC_RIGHTS_MASK);
7346
7347         generic_tree = proto_item_add_subtree(
7348                 item, ett_nt_access_mask_generic);
7349
7350         proto_tree_add_boolean(
7351                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7352                 access);
7353
7354         proto_tree_add_boolean(
7355                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7356                 access);
7357
7358         proto_tree_add_boolean(
7359                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7360                 access);
7361
7362         proto_tree_add_boolean(
7363                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7364                 access);
7365
7366         /* Reserved (??) */
7367
7368         proto_tree_add_boolean(
7369                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7370                 access);
7371
7372         /* Access system security */
7373
7374         proto_tree_add_boolean(
7375                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7376                 access);
7377
7378         /* Standard access rights */
7379
7380         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7381                                    "Standard rights: 0x%08x",
7382                                    access & STANDARD_RIGHTS_MASK);
7383
7384         standard_tree = proto_item_add_subtree(
7385                 item, ett_nt_access_mask_standard);
7386
7387         proto_tree_add_boolean(
7388                 standard_tree, hf_access_standard_synchronise, tvb, 
7389                 offset - 4, 4, access);
7390
7391         proto_tree_add_boolean(
7392                 standard_tree, hf_access_standard_write_owner, tvb, 
7393                 offset - 4, 4, access);
7394
7395         proto_tree_add_boolean(
7396                 standard_tree, hf_access_standard_write_dac, tvb, 
7397                 offset - 4, 4, access);
7398
7399         proto_tree_add_boolean(
7400                 standard_tree, hf_access_standard_read_control, tvb, 
7401                 offset - 4, 4, access);
7402
7403         proto_tree_add_boolean(
7404                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7405                 access);
7406
7407         /* Specific access rights.  Call the specific_rights_fn
7408            pointer if we have one, otherwise just display bits 0-15 in
7409            boring fashion. */
7410
7411         if (ami && ami->specific_rights_name)
7412                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7413                                            "%s specific rights: 0x%08x",
7414                                            ami->specific_rights_name,
7415                                            access & SPECIFIC_RIGHTS_MASK);
7416         else
7417                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7418                                            "Specific rights: 0x%08x",
7419                                            access & SPECIFIC_RIGHTS_MASK);
7420
7421         specific_tree = proto_item_add_subtree(
7422                 item, ett_nt_access_mask_specific);
7423
7424         if (ami && ami->specific_rights_fn) {
7425                 guint32 mapped_access = access;
7426                 proto_tree *specific_mapped;
7427
7428                 specific_mapped = proto_item_add_subtree(
7429                         item, ett_nt_access_mask_specific);
7430
7431                 ami->specific_rights_fn(
7432                         tvb, offset - 4, specific_tree, access);
7433
7434                 if (ami->generic_mapping)
7435                         map_generic_access(&access, ami->generic_mapping);
7436                 
7437                 if (ami->standard_mapping)
7438                         map_standard_access(&access, ami->standard_mapping);
7439
7440                 if (access != mapped_access) {
7441                         ami->specific_rights_fn(
7442                                 tvb, offset - 4, specific_mapped, 
7443                                 mapped_access);
7444                 }
7445                 
7446                 return offset;
7447         }
7448
7449         proto_tree_add_boolean(
7450                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7451                 access);
7452
7453         proto_tree_add_boolean(
7454                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7455                 access);
7456
7457         proto_tree_add_boolean(
7458                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7459                 access);
7460
7461         proto_tree_add_boolean(
7462                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7463                 access);
7464
7465         proto_tree_add_boolean(
7466                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7467                 access);
7468
7469         proto_tree_add_boolean(
7470                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7471                 access);
7472
7473         proto_tree_add_boolean(
7474                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7475                 access);
7476
7477         proto_tree_add_boolean(
7478                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7479                 access);
7480
7481         proto_tree_add_boolean(
7482                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7483                 access);
7484
7485         proto_tree_add_boolean(
7486                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7487                 access);
7488
7489         proto_tree_add_boolean(
7490                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7491                 access);
7492
7493         proto_tree_add_boolean(
7494                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7495                 access);
7496
7497         proto_tree_add_boolean(
7498                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7499                 access);
7500
7501         proto_tree_add_boolean(
7502                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7503                 access);
7504
7505         proto_tree_add_boolean(
7506                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7507                 access);
7508
7509         proto_tree_add_boolean(
7510                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7511                 access);
7512
7513         return offset;
7514 }
7515
7516 static int hf_smb_access_mask = -1;
7517
7518 static int
7519 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7520                   proto_tree *parent_tree, char *drep,
7521                   struct access_mask_info *ami)
7522 {
7523         proto_item *item = NULL;
7524         proto_tree *tree = NULL;
7525         int old_offset = offset;
7526         guint16 size;
7527         char *sid_str = NULL;
7528         guint8 type;
7529         guint8 flags;
7530
7531         if(parent_tree){
7532                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7533                                            "NT ACE: ");
7534                 tree = proto_item_add_subtree(item, ett_smb_ace);
7535         }
7536
7537         /* type */
7538         type = tvb_get_guint8(tvb, offset);
7539         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7540         offset += 1;
7541
7542         /* flags */
7543         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7544
7545         /* size */
7546         size = tvb_get_letohs(tvb, offset);
7547         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7548         offset += 2;
7549
7550         /* access mask */
7551         offset = dissect_nt_access_mask(
7552                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7553
7554         /* SID */
7555         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7556
7557         if (item)
7558                 proto_item_append_text(
7559                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7560                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7561
7562         g_free(sid_str);
7563
7564         proto_item_set_len(item, offset-old_offset);
7565
7566         /* Sometimes there is some spare space at the end of the ACE so use
7567            the size field to work out where the end is. */
7568
7569         return old_offset + size;
7570 }
7571
7572 static int
7573 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7574                proto_tree *parent_tree, char *drep, char *name,
7575                struct access_mask_info *ami)
7576 {
7577         proto_item *item = NULL;
7578         proto_tree *tree = NULL;
7579         int old_offset = offset;
7580         guint16 revision;
7581         guint32 num_aces;
7582
7583         if(parent_tree){
7584                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7585                                            "NT %s ACL", name);
7586                 tree = proto_item_add_subtree(item, ett_smb_acl);
7587         }
7588
7589         /* revision */
7590         revision = tvb_get_letohs(tvb, offset);
7591         proto_tree_add_uint(tree, hf_smb_acl_revision,
7592                 tvb, offset, 2, revision);
7593         offset += 2;
7594
7595         switch(revision){
7596         case 2:  /* only version we will ever see of this structure?*/
7597         case 3:
7598           /* size */
7599           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7600           offset += 2;
7601
7602           /* number of ace structures */
7603           num_aces = tvb_get_letohl(tvb, offset);
7604           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7605                               tvb, offset, 4, num_aces);
7606           offset += 4;
7607
7608           while(num_aces--){
7609             offset=dissect_nt_v2_ace(
7610                     tvb, offset, pinfo, tree, drep, ami);
7611           }
7612         }
7613
7614         proto_item_set_len(item, offset-old_offset);
7615         return offset;
7616 }
7617
7618 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7619   "OWNER is DEFAULTED",
7620   "Owner is NOT defaulted"
7621 };
7622 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7623   "GROUP is DEFAULTED",
7624   "Group is NOT defaulted"
7625 };
7626 static const true_false_string tfs_sec_desc_type_dacl_present = {
7627   "DACL is PRESENT",
7628   "DACL is NOT present"
7629 };
7630 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7631   "DACL is DEFAULTED",
7632   "DACL is NOT defaulted"
7633 };
7634 static const true_false_string tfs_sec_desc_type_sacl_present = {
7635   "SACL is PRESENT",
7636   "SACL is NOT present"
7637 };
7638 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7639   "SACL is DEFAULTED",
7640   "SACL is NOT defaulted"
7641 };
7642 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7643   "DACL has AUTO INHERIT REQUIRED",
7644   "DACL does NOT require auto inherit"
7645 };
7646 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7647   "SACL has AUTO INHERIT REQUIRED",
7648   "SACL does NOT require auto inherit"
7649 };
7650 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7651   "DACL is AUTO INHERITED",
7652   "DACL is NOT auto inherited"
7653 };
7654 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7655   "SACL is AUTO INHERITED",
7656   "SACL is NOT auto inherited"
7657 };
7658 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7659   "The DACL is PROTECTED",
7660   "The DACL is NOT protected"
7661 };
7662 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7663   "The SACL is PROTECTED",
7664   "The SACL is NOT protected"
7665 };
7666 static const true_false_string tfs_sec_desc_type_self_relative = {
7667   "This SecDesc is SELF RELATIVE",
7668   "This SecDesc is NOT self relative"
7669 };
7670
7671
7672 static int
7673 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7674 {
7675         proto_item *item = NULL;
7676         proto_tree *tree = NULL;
7677         guint16 mask;
7678
7679         mask = tvb_get_letohs(tvb, offset);
7680         if(parent_tree){
7681                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7682                                            "Type: 0x%04x", mask);
7683                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7684         }
7685
7686         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7687                                tvb, offset, 2, mask);
7688         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7689                                tvb, offset, 2, mask);
7690         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7691                                tvb, offset, 2, mask);
7692         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7693                                tvb, offset, 2, mask);
7694         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7695                                tvb, offset, 2, mask);
7696         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7697                                tvb, offset, 2, mask);
7698         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7699                                tvb, offset, 2, mask);
7700         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7701                                tvb, offset, 2, mask);
7702         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7703                                tvb, offset, 2, mask);
7704         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7705                                tvb, offset, 2, mask);
7706         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7707                                tvb, offset, 2, mask);
7708         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7709                                tvb, offset, 2, mask);
7710         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7711                                tvb, offset, 2, mask);
7712
7713
7714         offset += 2;
7715         return offset;
7716 }
7717
7718 int
7719 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7720                     proto_tree *parent_tree, char *drep, int len, 
7721                     struct access_mask_info *ami)
7722 {
7723         proto_item *item = NULL;
7724         proto_tree *tree = NULL;
7725         guint8 revision;
7726         int old_offset = offset;
7727         guint32 owner_sid_offset;
7728         guint32 group_sid_offset;
7729         guint32 sacl_offset;
7730         guint32 dacl_offset;
7731
7732         if(parent_tree){
7733                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7734                                            "NT Security Descriptor");
7735                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7736         }
7737
7738         /* revision */
7739         revision = tvb_get_guint8(tvb, offset);
7740         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7741                 tvb, offset, 1, revision);
7742         offset += 1;
7743
7744         /* next byte should be zero, for now just ignore it */
7745         offset += 1;
7746
7747
7748         switch(revision){
7749         case 1:  /* only version we will ever see of this structure?*/
7750           /* type */
7751           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7752
7753           /* offset to owner sid */
7754           owner_sid_offset = tvb_get_letohl(tvb, offset);
7755           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7756           offset += 4;
7757
7758           /* offset to group sid */
7759           group_sid_offset = tvb_get_letohl(tvb, offset);
7760           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7761           offset += 4;
7762
7763           /* offset to sacl */
7764           sacl_offset = tvb_get_letohl(tvb, offset);
7765           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7766           offset += 4;
7767
7768           /* offset to dacl */
7769           dacl_offset = tvb_get_letohl(tvb, offset);
7770           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7771           offset += 4;
7772
7773           /*owner SID*/
7774           if(owner_sid_offset){
7775             if (len == -1)
7776               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7777             else
7778               dissect_nt_sid(
7779                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7780           }
7781
7782           /*group SID*/
7783           if(group_sid_offset){
7784             dissect_nt_sid(
7785                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7786           }
7787
7788           /* sacl */
7789           if(sacl_offset){
7790             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7791                            drep, "System (SACL)", ami);
7792           }
7793
7794           /* dacl */
7795           if(dacl_offset){
7796             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7797                            drep, "User (DACL)", ami);
7798           }
7799
7800         }
7801
7802         return offset+len;
7803 }
7804
7805 static int
7806 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7807 {
7808         int old_offset, old_sid_offset;
7809         guint32 qsize;
7810
7811         do {
7812                 old_offset=offset;
7813
7814                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7815                 qsize=tvb_get_letohl(tvb, offset);
7816                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7817                 COUNT_BYTES_TRANS_SUBR(4);
7818
7819                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7820                 /* length of SID */
7821                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7822                 COUNT_BYTES_TRANS_SUBR(4);
7823
7824                 /* 16 unknown bytes */
7825                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7826                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7827                             offset, 8, TRUE);
7828                 COUNT_BYTES_TRANS_SUBR(8);
7829
7830                 /* number of bytes for used quota */
7831                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7832                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7833                 COUNT_BYTES_TRANS_SUBR(8);
7834
7835                 /* number of bytes for quota warning */
7836                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7837                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7838                 COUNT_BYTES_TRANS_SUBR(8);
7839
7840                 /* number of bytes for quota limit */
7841                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7842                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7843                 COUNT_BYTES_TRANS_SUBR(8);
7844
7845                 /* SID of the user */
7846                 old_sid_offset=offset;
7847                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7848                 *bcp -= (offset-old_sid_offset);
7849
7850                 if(qsize){
7851                         offset = old_offset+qsize;
7852                 }
7853         }while(qsize);
7854
7855
7856         return offset;
7857 }
7858
7859
7860 static int
7861 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7862 {
7863         proto_item *item = NULL;
7864         proto_tree *tree = NULL;
7865         smb_info_t *si;
7866         int old_offset = offset;
7867         guint16 bcp=bc; /* XXX fixme */
7868
7869         si = (smb_info_t *)pinfo->private_data;
7870
7871         if(parent_tree){
7872                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7873                                 "%s Data",
7874                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7875                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7876         }
7877
7878         switch(ntd->subcmd){
7879         case NT_TRANS_CREATE:
7880                 /* security descriptor */
7881                 if(ntd->sd_len){
7882                         offset = dissect_nt_sec_desc(
7883                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
7884                                 NULL);
7885                 }
7886
7887                 /* extended attributes */
7888                 if(ntd->ea_len){
7889                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7890                         offset += ntd->ea_len;
7891                 }
7892
7893                 break;
7894         case NT_TRANS_IOCTL:
7895                 /* ioctl data */
7896                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7897                 offset += bc;
7898
7899                 break;
7900         case NT_TRANS_SSD:
7901                 offset = dissect_nt_sec_desc(
7902                         tvb, offset, pinfo, tree, NULL, bc, NULL);
7903                 break;
7904         case NT_TRANS_NOTIFY:
7905                 break;
7906         case NT_TRANS_RENAME:
7907                 /* XXX not documented */
7908                 break;
7909         case NT_TRANS_QSD:
7910                 break;
7911         case NT_TRANS_GET_USER_QUOTA:
7912                 /* unknown 4 bytes */
7913                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7914                             offset, 4, TRUE);
7915                 offset += 4;
7916
7917                 /* length of SID */
7918                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7919                 offset +=4;
7920
7921                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7922                 break;
7923         case NT_TRANS_SET_USER_QUOTA:
7924                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7925                 break;
7926         }
7927
7928         /* ooops there were data we didnt know how to process */
7929         if((offset-old_offset) < bc){
7930                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7931                     bc - (offset-old_offset), TRUE);
7932                 offset += bc - (offset-old_offset);
7933         }
7934
7935         return offset;
7936 }
7937
7938 static int
7939 dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc)
7940 {
7941         proto_item *item = NULL;
7942         proto_tree *tree = NULL;
7943         smb_info_t *si;
7944         guint32 fn_len;
7945         const char *fn;
7946
7947         si = (smb_info_t *)pinfo->private_data;
7948
7949         if(parent_tree){
7950                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7951                                 "%s Parameters",
7952                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7953                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7954         }
7955
7956         switch(ntd->subcmd){
7957         case NT_TRANS_CREATE:
7958                 /* Create flags */
7959                 offset = dissect_nt_create_bits(tvb, tree, offset);
7960                 bc -= 4;
7961
7962                 /* root directory fid */
7963                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7964                 COUNT_BYTES(4);
7965
7966                 /* nt access mask */
7967                 offset = dissect_smb_access_mask(tvb, tree, offset);
7968                 bc -= 4;
7969
7970                 /* allocation size */
7971                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7972                 COUNT_BYTES(8);
7973
7974                 /* Extended File Attributes */
7975                 offset = dissect_file_ext_attr(tvb, tree, offset);
7976                 bc -= 4;
7977
7978                 /* share access */
7979                 offset = dissect_nt_share_access(tvb, tree, offset);
7980                 bc -= 4;
7981
7982                 /* create disposition */
7983                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7984                 COUNT_BYTES(4);
7985
7986                 /* create options */
7987                 offset = dissect_nt_create_options(tvb, tree, offset);
7988                 bc -= 4;
7989
7990                 /* sd length */
7991                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7992                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7993                 COUNT_BYTES(4);
7994
7995                 /* ea length */
7996                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7997                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7998                 COUNT_BYTES(4);
7999
8000                 /* file name len */
8001                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8002                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8003                 COUNT_BYTES(4);
8004
8005                 /* impersonation level */
8006                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8007                 COUNT_BYTES(4);
8008
8009                 /* security flags */
8010                 offset = dissect_nt_security_flags(tvb, tree, offset);
8011                 bc -= 1;
8012
8013                 /* file name */
8014                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8015                 if (fn != NULL) {
8016                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8017                                 fn);
8018                         COUNT_BYTES(fn_len);
8019                 }
8020
8021                 break;
8022         case NT_TRANS_IOCTL:
8023                 break;
8024         case NT_TRANS_SSD: {
8025                 guint16 fid;
8026
8027                 /* fid */
8028                 fid = tvb_get_letohs(tvb, offset);
8029                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8030                 offset += 2;
8031
8032                 /* 2 reserved bytes */
8033                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8034                 offset += 2;
8035
8036                 /* security information */
8037                 offset = dissect_security_information_mask(tvb, tree, offset);
8038                 break;
8039         }
8040         case NT_TRANS_NOTIFY:
8041                 break;
8042         case NT_TRANS_RENAME:
8043                 /* XXX not documented */
8044                 break;
8045         case NT_TRANS_QSD: {
8046                 guint16 fid;
8047
8048                 /* fid */
8049                 fid = tvb_get_letohs(tvb, offset);
8050                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8051                 offset += 2;
8052
8053                 /* 2 reserved bytes */
8054                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8055                 offset += 2;
8056
8057                 /* security information */
8058                 offset = dissect_security_information_mask(tvb, tree, offset);
8059                 break;
8060         }
8061         case NT_TRANS_GET_USER_QUOTA:
8062                 /* not decoded yet */
8063                 break;
8064         case NT_TRANS_SET_USER_QUOTA:
8065                 /* not decoded yet */
8066                 break;
8067         }
8068
8069         return offset;
8070 }
8071
8072 static int
8073 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8074 {
8075         proto_item *item = NULL;
8076         proto_tree *tree = NULL;
8077         smb_info_t *si;
8078         int old_offset = offset;
8079
8080         si = (smb_info_t *)pinfo->private_data;
8081
8082         if(parent_tree){
8083                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8084                                 "%s Setup",
8085                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8086                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8087         }
8088
8089         switch(ntd->subcmd){
8090         case NT_TRANS_CREATE:
8091                 break;
8092         case NT_TRANS_IOCTL: {
8093                 guint16 fid;
8094
8095                 /* function code */
8096                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8097                 offset += 4;
8098
8099                 /* fid */
8100                 fid = tvb_get_letohs(tvb, offset);
8101                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8102                 offset += 2;
8103
8104                 /* isfsctl */
8105                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8106                 offset += 1;
8107
8108                 /* isflags */
8109                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8110
8111                 break;
8112         }
8113         case NT_TRANS_SSD:
8114                 break;
8115         case NT_TRANS_NOTIFY: {
8116                 guint16 fid;
8117
8118                 /* completion filter */
8119                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8120
8121                 /* fid */
8122                 fid = tvb_get_letohs(tvb, offset);
8123                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8124                 offset += 2;
8125
8126                 /* watch tree */
8127                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8128                 offset += 1;
8129
8130                 /* reserved byte */
8131                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8132                 offset += 1;
8133
8134                 break;
8135         }
8136         case NT_TRANS_RENAME:
8137                 /* XXX not documented */
8138                 break;
8139         case NT_TRANS_QSD:
8140                 break;
8141         case NT_TRANS_GET_USER_QUOTA:
8142                 /* not decoded yet */
8143                 break;
8144         case NT_TRANS_SET_USER_QUOTA:
8145                 /* not decoded yet */
8146                 break;
8147         }
8148
8149         return old_offset+len;
8150 }
8151
8152
8153 static int
8154 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8155 {
8156         guint8 wc, sc;
8157         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8158         smb_info_t *si;
8159         smb_saved_info_t *sip;
8160         int subcmd;
8161         nt_trans_data ntd;
8162         guint16 bc;
8163         int padcnt;
8164         smb_nt_transact_info_t *nti;
8165
8166         si = (smb_info_t *)pinfo->private_data;
8167         sip = si->sip;
8168
8169         WORD_COUNT;
8170
8171         if(wc>=19){
8172                 /* primary request */
8173                 /* max setup count */
8174                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8175                 offset += 1;
8176
8177                 /* 2 reserved bytes */
8178                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8179                 offset += 2;
8180         } else {
8181                 /* secondary request */
8182                 /* 3 reserved bytes */
8183                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8184                 offset += 3;
8185         }
8186
8187
8188         /* total param count */
8189         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8190         offset += 4;
8191
8192         /* total data count */
8193         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8194         offset += 4;
8195
8196         if(wc>=19){
8197                 /* primary request */
8198                 /* max param count */
8199                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8200                 offset += 4;
8201
8202                 /* max data count */
8203                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8204                 offset += 4;
8205         }
8206
8207         /* param count */
8208         pc = tvb_get_letohl(tvb, offset);
8209         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8210         offset += 4;
8211
8212         /* param offset */
8213         po = tvb_get_letohl(tvb, offset);
8214         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8215         offset += 4;
8216
8217         /* param displacement */
8218         if(wc>=19){
8219                 /* primary request*/
8220                 pd = 0;
8221         } else {
8222                 /* secondary request */
8223                 pd = tvb_get_letohl(tvb, offset);
8224                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8225                 offset += 4;
8226         }
8227
8228         /* data count */
8229         dc = tvb_get_letohl(tvb, offset);
8230         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8231         offset += 4;
8232
8233         /* data offset */
8234         od = tvb_get_letohl(tvb, offset);
8235         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8236         offset += 4;
8237
8238         /* data displacement */
8239         if(wc>=19){
8240                 /* primary request */
8241                 dd = 0;
8242         } else {
8243                 /* secondary request */
8244                 dd = tvb_get_letohl(tvb, offset);
8245                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8246                 offset += 4;
8247         }
8248
8249         /* setup count */
8250         if(wc>=19){
8251                 /* primary request */
8252                 sc = tvb_get_guint8(tvb, offset);
8253                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8254                 offset += 1;
8255         } else {
8256                 /* secondary request */
8257                 sc = 0;
8258         }
8259
8260         /* function */
8261         if(wc>=19){
8262                 /* primary request */
8263                 subcmd = tvb_get_letohs(tvb, offset);
8264                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8265                 if(check_col(pinfo->cinfo, COL_INFO)){
8266                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8267                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8268                 }
8269                 ntd.subcmd = subcmd;
8270                 if (!si->unidir) {
8271                         if(!pinfo->fd->flags.visited){
8272                                 /*
8273                                  * Allocate a new smb_nt_transact_info_t
8274                                  * structure.
8275                                  */
8276                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8277                                 nti->subcmd = subcmd;
8278                                 sip->extra_info = nti;
8279                         }
8280                 }
8281         } else {
8282                 /* secondary request */
8283                 if(check_col(pinfo->cinfo, COL_INFO)){
8284                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8285                 }
8286         }
8287         offset += 2;
8288
8289         /* this is a padding byte */
8290         if(offset%1){
8291                 /* pad byte */
8292                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8293                 offset += 1;
8294         }
8295
8296         /* if there were any setup bytes, decode them */
8297         if(sc){
8298                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8299                 offset += sc*2;
8300         }
8301
8302         BYTE_COUNT;
8303
8304         /* parameters */
8305         if(po>(guint32)offset){
8306                 /* We have some initial padding bytes.
8307                 */
8308                 padcnt = po-offset;
8309                 if (padcnt > bc)
8310                         padcnt = bc;
8311                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8312                 COUNT_BYTES(padcnt);
8313         }
8314         if(pc){
8315                 CHECK_BYTE_COUNT(pc);
8316                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8317                 COUNT_BYTES(pc);
8318         }
8319
8320         /* data */
8321         if(od>(guint32)offset){
8322                 /* We have some initial padding bytes.
8323                 */
8324                 padcnt = od-offset;
8325                 if (padcnt > bc)
8326                         padcnt = bc;
8327                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8328                 COUNT_BYTES(padcnt);
8329         }
8330         if(dc){
8331                 CHECK_BYTE_COUNT(dc);
8332                 dissect_nt_trans_data_request(
8333                         tvb, pinfo, offset, tree, dc, &ntd);
8334                 COUNT_BYTES(dc);
8335         }
8336
8337         END_OF_SMB
8338
8339         return offset;
8340 }
8341
8342
8343
8344 static int
8345 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8346                                int offset, proto_tree *parent_tree, int len,
8347                                nt_trans_data *ntd _U_)
8348 {
8349         proto_item *item = NULL;
8350         proto_tree *tree = NULL;
8351         smb_info_t *si;
8352         smb_nt_transact_info_t *nti;
8353         guint16 bcp;
8354
8355         si = (smb_info_t *)pinfo->private_data;
8356         if (si->sip != NULL)
8357                 nti = si->sip->extra_info;
8358         else
8359                 nti = NULL;
8360
8361         if(parent_tree){
8362                 if(nti != NULL){
8363                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8364                                 "%s Data",
8365                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8366                 } else {
8367                         /*
8368                          * We never saw the request to which this is a
8369                          * response.
8370                          */
8371                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8372                                 "Unknown NT Transaction Data (matching request not seen)");
8373                 }
8374                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8375         }
8376
8377         if (nti == NULL) {
8378                 offset += len;
8379                 return offset;
8380         }
8381         switch(nti->subcmd){
8382         case NT_TRANS_CREATE:
8383                 break;
8384         case NT_TRANS_IOCTL:
8385                 /* ioctl data */
8386                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8387                 offset += len;
8388
8389                 break;
8390         case NT_TRANS_SSD:
8391                 break;
8392         case NT_TRANS_NOTIFY:
8393                 break;
8394         case NT_TRANS_RENAME:
8395                 /* XXX not documented */
8396                 break;
8397         case NT_TRANS_QSD: {
8398                 /*
8399                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8400                  * which may be documented in the Win32 documentation
8401                  * somewhere.
8402                  */
8403                 offset = dissect_nt_sec_desc(
8404                         tvb, offset, pinfo, tree, NULL, len, NULL);
8405                 break;
8406         }
8407         case NT_TRANS_GET_USER_QUOTA:
8408                 bcp=len;
8409                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8410                 break;
8411         case NT_TRANS_SET_USER_QUOTA:
8412                 /* not decoded yet */
8413                 break;
8414         }
8415
8416         return offset;
8417 }
8418
8419 static int
8420 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8421                                 int offset, proto_tree *parent_tree,
8422                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8423 {
8424         proto_item *item = NULL;
8425         proto_tree *tree = NULL;
8426         guint32 fn_len;
8427         const char *fn;
8428         smb_info_t *si;
8429         smb_nt_transact_info_t *nti;
8430         guint16 fid;
8431         int old_offset;
8432         guint32 neo;
8433         int padcnt;
8434
8435         si = (smb_info_t *)pinfo->private_data;
8436         if (si->sip != NULL)
8437                 nti = si->sip->extra_info;
8438         else
8439                 nti = NULL;
8440
8441         if(parent_tree){
8442                 if(nti != NULL){
8443                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8444                                 "%s Parameters",
8445                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8446                 } else {
8447                         /*
8448                          * We never saw the request to which this is a
8449                          * response.
8450                          */
8451                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8452                                 "Unknown NT Transaction Parameters (matching request not seen)");
8453                 }
8454                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8455         }
8456
8457         if (nti == NULL) {
8458                 offset += len;
8459                 return offset;
8460         }
8461         switch(nti->subcmd){
8462         case NT_TRANS_CREATE:
8463                 /* oplock level */
8464                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8465                 offset += 1;
8466
8467                 /* reserved byte */
8468                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8469                 offset += 1;
8470
8471                 /* fid */
8472                 fid = tvb_get_letohs(tvb, offset);
8473                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8474                 offset += 2;
8475
8476                 /* create action */
8477                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8478                 offset += 4;
8479
8480                 /* ea error offset */
8481                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8482                 offset += 4;
8483
8484                 /* create time */
8485                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8486                         hf_smb_create_time);
8487
8488                 /* access time */
8489                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8490                         hf_smb_access_time);
8491
8492                 /* last write time */
8493                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8494                         hf_smb_last_write_time);
8495
8496                 /* last change time */
8497                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8498                         hf_smb_change_time);
8499
8500                 /* Extended File Attributes */
8501                 offset = dissect_file_ext_attr(tvb, tree, offset);
8502
8503                 /* allocation size */
8504                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8505                 offset += 8;
8506
8507                 /* end of file */
8508                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8509                 offset += 8;
8510
8511                 /* File Type */
8512                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8513                 offset += 2;
8514
8515                 /* device state */
8516                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8517
8518                 /* is directory */
8519                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8520                 offset += 1;
8521                 break;
8522         case NT_TRANS_IOCTL:
8523                 break;
8524         case NT_TRANS_SSD:
8525                 break;
8526         case NT_TRANS_NOTIFY:
8527                 while(len){
8528                         old_offset = offset;
8529
8530                         /* next entry offset */
8531                         neo = tvb_get_letohl(tvb, offset);
8532                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8533                         COUNT_BYTES(4);
8534                         len -= 4;
8535                         /* broken implementations */
8536                         if(len<0)break;
8537
8538                         /* action */
8539                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8540                         COUNT_BYTES(4);
8541                         len -= 4;
8542                         /* broken implementations */
8543                         if(len<0)break;
8544
8545                         /* file name len */
8546                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8547                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8548                         COUNT_BYTES(4);
8549                         len -= 4;
8550                         /* broken implementations */
8551                         if(len<0)break;
8552
8553                         /* file name */
8554                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8555                         if (fn == NULL)
8556                                 break;
8557                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8558                                 fn);
8559                         COUNT_BYTES(fn_len);
8560                         len -= fn_len;
8561                         /* broken implementations */
8562                         if(len<0)break;
8563
8564                         if (neo == 0)
8565                                 break;  /* no more structures */
8566
8567                         /* skip to next structure */
8568                         padcnt = (old_offset + neo) - offset;
8569                         if (padcnt < 0) {
8570                                 /*
8571                                  * XXX - this is bogus; flag it?
8572                                  */
8573                                 padcnt = 0;
8574                         }
8575                         if (padcnt != 0) {
8576                                 COUNT_BYTES(padcnt);
8577                                 len -= padcnt;
8578                                 /* broken implementations */
8579                                 if(len<0)break;
8580                         }
8581                 }
8582                 break;
8583         case NT_TRANS_RENAME:
8584                 /* XXX not documented */
8585                 break;
8586         case NT_TRANS_QSD:
8587                 /*
8588                  * This appears to be the size of the security
8589                  * descriptor; the calling sequence of
8590                  * "ZwQuerySecurityObject()" suggests that it would
8591                  * be.  The actual security descriptor wouldn't
8592                  * follow if the max data count in the request
8593                  * was smaller; this lets the client know how
8594                  * big a buffer it needs to provide.
8595                  */
8596                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8597                 offset += 4;
8598                 break;
8599         case NT_TRANS_GET_USER_QUOTA:
8600                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8601                         tvb_get_letohl(tvb, offset));
8602                 offset += 4;
8603                 break;
8604         case NT_TRANS_SET_USER_QUOTA:
8605                 /* not decoded yet */
8606                 break;
8607         }
8608
8609         return offset;
8610 }
8611
8612 static int
8613 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8614                                 int offset, proto_tree *parent_tree,
8615                                 int len, nt_trans_data *ntd _U_)
8616 {
8617         proto_item *item = NULL;
8618         proto_tree *tree = NULL;
8619         smb_info_t *si;
8620         smb_nt_transact_info_t *nti;
8621
8622         si = (smb_info_t *)pinfo->private_data;
8623         if (si->sip != NULL)
8624                 nti = si->sip->extra_info;
8625         else
8626                 nti = NULL;
8627
8628         if(parent_tree){
8629                 if(nti != NULL){
8630                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8631                                 "%s Setup",
8632                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8633                 } else {
8634                         /*
8635                          * We never saw the request to which this is a
8636                          * response.
8637                          */
8638                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8639                                 "Unknown NT Transaction Setup (matching request not seen)");
8640                 }
8641                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8642         }
8643
8644         if (nti == NULL) {
8645                 offset += len;
8646                 return offset;
8647         }
8648         switch(nti->subcmd){
8649         case NT_TRANS_CREATE:
8650                 break;
8651         case NT_TRANS_IOCTL:
8652                 break;
8653         case NT_TRANS_SSD:
8654                 break;
8655         case NT_TRANS_NOTIFY:
8656                 break;
8657         case NT_TRANS_RENAME:
8658                 /* XXX not documented */
8659                 break;
8660         case NT_TRANS_QSD:
8661                 break;
8662         case NT_TRANS_GET_USER_QUOTA:
8663                 /* not decoded yet */
8664                 break;
8665         case NT_TRANS_SET_USER_QUOTA:
8666                 /* not decoded yet */
8667                 break;
8668         }
8669
8670         return offset;
8671 }
8672
8673 static int
8674 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8675 {
8676         guint8 wc, sc;
8677         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8678         guint32 td=0, tp=0;
8679         smb_info_t *si;
8680         smb_nt_transact_info_t *nti;
8681         static nt_trans_data ntd;
8682         guint16 bc;
8683         int padcnt;
8684         fragment_data *r_fd = NULL;
8685         tvbuff_t *pd_tvb=NULL;
8686         gboolean save_fragmented;
8687
8688         si = (smb_info_t *)pinfo->private_data;
8689         if (si->sip != NULL)
8690                 nti = si->sip->extra_info;
8691         else
8692                 nti = NULL;
8693
8694         /* primary request */
8695         if(nti != NULL){
8696                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8697                 if(check_col(pinfo->cinfo, COL_INFO)){
8698                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8699                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8700                 }
8701         } else {
8702                 proto_tree_add_text(tree, tvb, offset, 0,
8703                         "Function: <unknown function - could not find matching request>");
8704                 if(check_col(pinfo->cinfo, COL_INFO)){
8705                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8706                 }
8707         }
8708
8709         WORD_COUNT;
8710
8711         /* 3 reserved bytes */
8712         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8713         offset += 3;
8714
8715         /* total param count */
8716         tp = tvb_get_letohl(tvb, offset);
8717         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8718         offset += 4;
8719
8720         /* total data count */
8721         td = tvb_get_letohl(tvb, offset);
8722         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8723         offset += 4;
8724
8725         /* param count */
8726         pc = tvb_get_letohl(tvb, offset);
8727         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8728         offset += 4;
8729
8730         /* param offset */
8731         po = tvb_get_letohl(tvb, offset);
8732         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8733         offset += 4;
8734
8735         /* param displacement */
8736         pd = tvb_get_letohl(tvb, offset);
8737         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8738         offset += 4;
8739
8740         /* data count */
8741         dc = tvb_get_letohl(tvb, offset);
8742         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8743         offset += 4;
8744
8745         /* data offset */
8746         od = tvb_get_letohl(tvb, offset);
8747         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8748         offset += 4;
8749
8750         /* data displacement */
8751         dd = tvb_get_letohl(tvb, offset);
8752         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8753         offset += 4;
8754
8755         /* setup count */
8756         sc = tvb_get_guint8(tvb, offset);
8757         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8758         offset += 1;
8759
8760         /* setup data */
8761         if(sc){
8762                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8763                 offset += sc*2;
8764         }
8765
8766         BYTE_COUNT;
8767
8768         /* reassembly of SMB NT Transaction data payload.
8769            In this section we do reassembly of both the data and parameters
8770            blocks of the SMB transaction command.
8771         */
8772         save_fragmented = pinfo->fragmented;
8773         /* do we need reassembly? */
8774         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8775                 /* oh yeah, either data or parameter section needs
8776                    reassembly...
8777                 */
8778                 pinfo->fragmented = TRUE;
8779                 if(smb_trans_reassembly){
8780                         /* ...and we were told to do reassembly */
8781                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8782                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8783                                                              po, pc, pd, td+tp);
8784
8785                         }
8786                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8787                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8788                                                              od, dc, dd+tp, td+tp);
8789                         }
8790                 }
8791         }
8792
8793         /* if we got a reassembled fd structure from the reassembly routine we
8794            must create pd_tvb from it
8795         */
8796         if(r_fd){
8797                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8798                                              r_fd->datalen);
8799                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8800                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8801
8802                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8803         }
8804
8805
8806         if(pd_tvb){
8807           /* we have reassembled data, grab param and data from there */
8808           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8809                                           &ntd, tvb_length(pd_tvb));
8810           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8811         } else {
8812           /* we do not have reassembled data, just use what we have in the
8813              packet as well as we can */
8814           /* parameters */
8815           if(po>(guint32)offset){
8816             /* We have some initial padding bytes.
8817              */
8818             padcnt = po-offset;
8819             if (padcnt > bc)
8820               padcnt = bc;
8821             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8822             COUNT_BYTES(padcnt);
8823           }
8824           if(pc){
8825             CHECK_BYTE_COUNT(pc);
8826             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8827             COUNT_BYTES(pc);
8828           }
8829
8830           /* data */
8831           if(od>(guint32)offset){
8832             /* We have some initial padding bytes.
8833              */
8834             padcnt = od-offset;
8835             if (padcnt > bc)
8836               padcnt = bc;
8837             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8838             COUNT_BYTES(padcnt);
8839           }
8840           if(dc){
8841             CHECK_BYTE_COUNT(dc);
8842             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8843             COUNT_BYTES(dc);
8844           }
8845         }
8846         pinfo->fragmented = save_fragmented;
8847
8848         END_OF_SMB
8849
8850         return offset;
8851 }
8852
8853 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8854    NT Transaction command  ends here
8855    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8856
8857 static const value_string print_mode_vals[] = {
8858         {0,     "Text Mode"},
8859         {1,     "Graphics Mode"},
8860         {0, NULL}
8861 };
8862
8863 static int
8864 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8865 {
8866         smb_info_t *si = pinfo->private_data;
8867         int fn_len;
8868         const char *fn;
8869         guint8 wc;
8870         guint16 bc;
8871
8872         WORD_COUNT;
8873
8874         /* setup len */
8875         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8876         offset += 2;
8877
8878         /* print mode */
8879         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8880         offset += 2;
8881
8882         BYTE_COUNT;
8883
8884         /* buffer format */
8885         CHECK_BYTE_COUNT(1);
8886         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8887         COUNT_BYTES(1);
8888
8889         /* print identifier */
8890         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8891         if (fn == NULL)
8892                 goto endofcommand;
8893         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8894                 fn);
8895         COUNT_BYTES(fn_len);
8896
8897         END_OF_SMB
8898
8899         return offset;
8900 }
8901
8902
8903 static int
8904 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8905 {
8906         int cnt;
8907         guint8 wc;
8908         guint16 bc, fid;
8909
8910         WORD_COUNT;
8911
8912         /* fid */
8913         fid = tvb_get_letohs(tvb, offset);
8914         add_fid(tvb, pinfo, tree, offset, 2, fid);
8915         offset += 2;
8916
8917         BYTE_COUNT;
8918
8919         /* buffer format */
8920         CHECK_BYTE_COUNT(1);
8921         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8922         COUNT_BYTES(1);
8923
8924         /* data len */
8925         CHECK_BYTE_COUNT(2);
8926         cnt = tvb_get_letohs(tvb, offset);
8927         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8928         COUNT_BYTES(2);
8929
8930         /* file data */
8931         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8932
8933         END_OF_SMB
8934
8935         return offset;
8936 }
8937
8938
8939 static const value_string print_status_vals[] = {
8940         {1,     "Held or Stopped"},
8941         {2,     "Printing"},
8942         {3,     "Awaiting print"},
8943         {4,     "In intercept"},
8944         {5,     "File had error"},
8945         {6,     "Printer error"},
8946         {0, NULL}
8947 };
8948
8949 static int
8950 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8951 {
8952         guint8 wc;
8953         guint16 bc;
8954
8955         WORD_COUNT;
8956
8957         /* max count */
8958         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8959         offset += 2;
8960
8961         /* start index */
8962         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8963         offset += 2;
8964
8965         BYTE_COUNT;
8966
8967         END_OF_SMB
8968
8969         return offset;
8970 }
8971
8972 static int
8973 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8974     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8975 {
8976         proto_item *item = NULL;
8977         proto_tree *tree = NULL;
8978         smb_info_t *si = pinfo->private_data;
8979         int fn_len;
8980         const char *fn;
8981
8982         if(parent_tree){
8983                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8984                         "Queue entry");
8985                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8986         }
8987
8988         /* queued time */
8989         CHECK_BYTE_COUNT_SUBR(4);
8990         offset = dissect_smb_datetime(tvb, tree, offset,
8991                 hf_smb_print_queue_date,
8992                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8993         *bcp -= 4;
8994
8995         /* status */
8996         CHECK_BYTE_COUNT_SUBR(1);
8997         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8998         COUNT_BYTES_SUBR(1);
8999
9000         /* spool file number */
9001         CHECK_BYTE_COUNT_SUBR(2);
9002         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9003         COUNT_BYTES_SUBR(2);
9004
9005         /* spool file size */
9006         CHECK_BYTE_COUNT_SUBR(4);
9007         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9008         COUNT_BYTES_SUBR(4);
9009
9010         /* reserved byte */
9011         CHECK_BYTE_COUNT_SUBR(1);
9012         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9013         COUNT_BYTES_SUBR(1);
9014
9015         /* file name */
9016         fn_len = 16;
9017         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9018         CHECK_STRING_SUBR(fn);
9019         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9020                 fn);
9021         COUNT_BYTES_SUBR(fn_len);
9022
9023         *trunc = FALSE;
9024         return offset;
9025 }
9026
9027 static int
9028 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9029 {
9030         guint16 cnt=0, len;
9031         guint8 wc;
9032         guint16 bc;
9033         gboolean trunc;
9034
9035         WORD_COUNT;
9036
9037         /* count */
9038         cnt = tvb_get_letohs(tvb, offset);
9039         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9040         offset += 2;
9041
9042         /* restart index */
9043         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9044         offset += 2;
9045
9046         BYTE_COUNT;
9047
9048         /* buffer format */
9049         CHECK_BYTE_COUNT(1);
9050         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9051         COUNT_BYTES(1);
9052
9053         /* data len */
9054         CHECK_BYTE_COUNT(2);
9055         len = tvb_get_letohs(tvb, offset);
9056         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9057         COUNT_BYTES(2);
9058
9059         /* queue elements */
9060         while(cnt--){
9061                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9062                     &bc, &trunc);
9063                 if (trunc)
9064                         goto endofcommand;
9065         }
9066
9067         END_OF_SMB
9068
9069         return offset;
9070 }
9071
9072
9073 static int
9074 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9075 {
9076         int name_len;
9077         guint16 bc;
9078         guint8 wc;
9079         guint16 message_len;
9080
9081         WORD_COUNT;
9082
9083         BYTE_COUNT;
9084
9085         /* buffer format */
9086         CHECK_BYTE_COUNT(1);
9087         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9088         COUNT_BYTES(1);
9089
9090         /* originator name */
9091         /* XXX - what if this runs past bc? */
9092         name_len = tvb_strsize(tvb, offset);
9093         CHECK_BYTE_COUNT(name_len);
9094         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9095             name_len, TRUE);
9096         COUNT_BYTES(name_len);
9097
9098         /* buffer format */
9099         CHECK_BYTE_COUNT(1);
9100         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9101         COUNT_BYTES(1);
9102
9103         /* destination name */
9104         /* XXX - what if this runs past bc? */
9105         name_len = tvb_strsize(tvb, offset);
9106         CHECK_BYTE_COUNT(name_len);
9107         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9108             name_len, TRUE);
9109         COUNT_BYTES(name_len);
9110
9111         /* buffer format */
9112         CHECK_BYTE_COUNT(1);
9113         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9114         COUNT_BYTES(1);
9115
9116         /* message len */
9117         CHECK_BYTE_COUNT(2);
9118         message_len = tvb_get_letohs(tvb, offset);
9119         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9120             message_len);
9121         COUNT_BYTES(2);
9122
9123         /* message */
9124         CHECK_BYTE_COUNT(message_len);
9125         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9126             TRUE);
9127         COUNT_BYTES(message_len);
9128
9129         END_OF_SMB
9130
9131         return offset;
9132 }
9133
9134 static int
9135 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9136 {
9137         int name_len;
9138         guint16 bc;
9139         guint8 wc;
9140
9141         WORD_COUNT;
9142
9143         BYTE_COUNT;
9144
9145         /* buffer format */
9146         CHECK_BYTE_COUNT(1);
9147         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9148         COUNT_BYTES(1);
9149
9150         /* originator name */
9151         /* XXX - what if this runs past bc? */
9152         name_len = tvb_strsize(tvb, offset);
9153         CHECK_BYTE_COUNT(name_len);
9154         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9155             name_len, TRUE);
9156         COUNT_BYTES(name_len);
9157
9158         /* buffer format */
9159         CHECK_BYTE_COUNT(1);
9160         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9161         COUNT_BYTES(1);
9162
9163         /* destination name */
9164         /* XXX - what if this runs past bc? */
9165         name_len = tvb_strsize(tvb, offset);
9166         CHECK_BYTE_COUNT(name_len);
9167         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9168             name_len, TRUE);
9169         COUNT_BYTES(name_len);
9170
9171         END_OF_SMB
9172
9173         return offset;
9174 }
9175
9176 static int
9177 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9178 {
9179         guint16 bc;
9180         guint8 wc;
9181
9182         WORD_COUNT;
9183
9184         /* message group ID */
9185         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9186         offset += 2;
9187
9188         BYTE_COUNT;
9189
9190         END_OF_SMB
9191
9192         return offset;
9193 }
9194
9195 static int
9196 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9197 {
9198         guint16 bc;
9199         guint8 wc;
9200         guint16 message_len;
9201
9202         WORD_COUNT;
9203
9204         BYTE_COUNT;
9205
9206         /* buffer format */
9207         CHECK_BYTE_COUNT(1);
9208         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9209         COUNT_BYTES(1);
9210
9211         /* message len */
9212         CHECK_BYTE_COUNT(2);
9213         message_len = tvb_get_letohs(tvb, offset);
9214         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9215             message_len);
9216         COUNT_BYTES(2);
9217
9218         /* message */
9219         CHECK_BYTE_COUNT(message_len);
9220         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9221             TRUE);
9222         COUNT_BYTES(message_len);
9223
9224         END_OF_SMB
9225
9226         return offset;
9227 }
9228
9229 static int
9230 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9231 {
9232         int name_len;
9233         guint16 bc;
9234         guint8 wc;
9235
9236         WORD_COUNT;
9237
9238         BYTE_COUNT;
9239
9240         /* buffer format */
9241         CHECK_BYTE_COUNT(1);
9242         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9243         COUNT_BYTES(1);
9244
9245         /* forwarded name */
9246         /* XXX - what if this runs past bc? */
9247         name_len = tvb_strsize(tvb, offset);
9248         CHECK_BYTE_COUNT(name_len);
9249         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9250             name_len, TRUE);
9251         COUNT_BYTES(name_len);
9252
9253         END_OF_SMB
9254
9255         return offset;
9256 }
9257
9258 static int
9259 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9260 {
9261         int name_len;
9262         guint16 bc;
9263         guint8 wc;
9264
9265         WORD_COUNT;
9266
9267         BYTE_COUNT;
9268
9269         /* buffer format */
9270         CHECK_BYTE_COUNT(1);
9271         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9272         COUNT_BYTES(1);
9273
9274         /* machine name */
9275         /* XXX - what if this runs past bc? */
9276         name_len = tvb_strsize(tvb, offset);
9277         CHECK_BYTE_COUNT(name_len);
9278         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9279             name_len, TRUE);
9280         COUNT_BYTES(name_len);
9281
9282         END_OF_SMB
9283
9284         return offset;
9285 }
9286
9287
9288 static int
9289 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9290 {
9291         guint8  wc, cmd=0xff;
9292         guint16 andxoffset=0;
9293         guint16 bc;
9294         smb_info_t *si = pinfo->private_data;
9295         int fn_len;
9296         const char *fn;
9297
9298         WORD_COUNT;
9299
9300         /* next smb command */
9301         cmd = tvb_get_guint8(tvb, offset);
9302         if(cmd!=0xff){
9303                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9304         } else {
9305                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
9306         }
9307         offset += 1;
9308
9309         /* reserved byte */
9310         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9311         offset += 1;
9312
9313         /* andxoffset */
9314         andxoffset = tvb_get_letohs(tvb, offset);
9315         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9316         offset += 2;
9317
9318         /* reserved byte */
9319         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9320         offset += 1;
9321
9322         /* file name len */
9323         fn_len = tvb_get_letohs(tvb, offset);
9324         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9325         offset += 2;
9326
9327         /* Create flags */
9328         offset = dissect_nt_create_bits(tvb, tree, offset);
9329
9330         /* root directory fid */
9331         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9332         offset += 4;
9333
9334         /* nt access mask */
9335         offset = dissect_smb_access_mask(tvb, tree, offset);
9336
9337         /* allocation size */
9338         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9339         offset += 8;
9340
9341         /* Extended File Attributes */
9342         offset = dissect_file_ext_attr(tvb, tree, offset);
9343
9344         /* share access */
9345         offset = dissect_nt_share_access(tvb, tree, offset);
9346
9347         /* create disposition */
9348         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9349         offset += 4;
9350
9351         /* create options */
9352         offset = dissect_nt_create_options(tvb, tree, offset);
9353
9354         /* impersonation level */
9355         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9356         offset += 4;
9357
9358         /* security flags */
9359         offset = dissect_nt_security_flags(tvb, tree, offset);
9360
9361         BYTE_COUNT;
9362
9363         /* file name */
9364         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9365         if (fn == NULL)
9366                 goto endofcommand;
9367         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9368                 fn);
9369         COUNT_BYTES(fn_len);
9370
9371         if (check_col(pinfo->cinfo, COL_INFO)) {
9372                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9373         }
9374
9375         END_OF_SMB
9376
9377         /* call AndXCommand (if there are any) */
9378         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9379
9380         return offset;
9381 }
9382
9383
9384 static int
9385 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9386 {
9387         guint8  wc, cmd=0xff;
9388         guint16 andxoffset=0;
9389         guint16 bc;
9390         guint16 fid;
9391
9392         WORD_COUNT;
9393
9394         /* next smb command */
9395         cmd = tvb_get_guint8(tvb, offset);
9396         if(cmd!=0xff){
9397                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9398         } else {
9399                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
9400         }
9401         offset += 1;
9402
9403         /* reserved byte */
9404         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9405         offset += 1;
9406
9407         /* andxoffset */
9408         andxoffset = tvb_get_letohs(tvb, offset);
9409         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9410         offset += 2;
9411
9412         /* oplock level */
9413         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9414         offset += 1;
9415
9416         /* fid */
9417         fid = tvb_get_letohs(tvb, offset);
9418         add_fid(tvb, pinfo, tree, offset, 2, fid);
9419         offset += 2;
9420
9421         /* create action */
9422         /*XXX is this really the same as create disposition in the request? it looks so*/
9423         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9424         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9425         offset += 4;
9426
9427         /* create time */
9428         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9429
9430         /* access time */
9431         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9432
9433         /* last write time */
9434         offset = dissect_smb_64bit_time(tvb, tree, offset,
9435                 hf_smb_last_write_time);
9436
9437         /* last change time */
9438         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9439
9440         /* Extended File Attributes */
9441         offset = dissect_file_ext_attr(tvb, tree, offset);
9442
9443         /* allocation size */
9444         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9445         offset += 8;
9446
9447         /* end of file */
9448         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9449         offset += 8;
9450
9451         /* File Type */
9452         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9453         offset += 2;
9454
9455         /* IPC State */
9456         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9457
9458         /* is directory */
9459         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9460         offset += 1;
9461
9462         BYTE_COUNT;
9463
9464         END_OF_SMB
9465
9466         /* call AndXCommand (if there are any) */
9467         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9468
9469         return offset;
9470 }
9471
9472
9473 static int
9474 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9475 {
9476         guint8 wc;
9477         guint16 bc;
9478
9479         WORD_COUNT;
9480
9481         BYTE_COUNT;
9482
9483         END_OF_SMB
9484
9485         return offset;
9486 }
9487
9488 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9489    BEGIN Transaction/Transaction2 Primary and secondary requests
9490    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9491
9492
9493 const value_string trans2_cmd_vals[] = {
9494         { 0x00,         "OPEN2" },
9495         { 0x01,         "FIND_FIRST2" },
9496         { 0x02,         "FIND_NEXT2" },
9497         { 0x03,         "QUERY_FS_INFORMATION" },
9498         { 0x04,         "SET_FS_QUOTA" },
9499         { 0x05,         "QUERY_PATH_INFORMATION" },
9500         { 0x06,         "SET_PATH_INFORMATION" },
9501         { 0x07,         "QUERY_FILE_INFORMATION" },
9502         { 0x08,         "SET_FILE_INFORMATION" },
9503         { 0x09,         "FSCTL" },
9504         { 0x0A,         "IOCTL2" },
9505         { 0x0B,         "FIND_NOTIFY_FIRST" },
9506         { 0x0C,         "FIND_NOTIFY_NEXT" },
9507         { 0x0D,         "CREATE_DIRECTORY" },
9508         { 0x0E,         "SESSION_SETUP" },
9509         { 0x10,         "GET_DFS_REFERRAL" },
9510         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9511         { 0,    NULL }
9512 };
9513
9514 static const true_false_string tfs_tf_dtid = {
9515         "Also DISCONNECT TID",
9516         "Do NOT disconnect TID"
9517 };
9518 static const true_false_string tfs_tf_owt = {
9519         "One Way Transaction (NO RESPONSE)",
9520         "Two way transaction"
9521 };
9522
9523 static const true_false_string tfs_ff2_backup = {
9524         "Find WITH backup intent",
9525         "No backup intent"
9526 };
9527 static const true_false_string tfs_ff2_continue = {
9528         "CONTINUE search from previous position",
9529         "New search, do NOT continue from previous position"
9530 };
9531 static const true_false_string tfs_ff2_resume = {
9532         "Return RESUME keys",
9533         "Do NOT return resume keys"
9534 };
9535 static const true_false_string tfs_ff2_close_eos = {
9536         "CLOSE search if END OF SEARCH is reached",
9537         "Do NOT close search if end of search reached"
9538 };
9539 static const true_false_string tfs_ff2_close = {
9540         "CLOSE search after this request",
9541         "Do NOT close search after this request"
9542 };
9543
9544 /* used by
9545    TRANS2_FIND_FIRST2
9546 */
9547 static const value_string ff2_il_vals[] = {
9548         { 1,            "Info Standard  (4.3.4.1)"},
9549         { 2,            "Info Query EA Size  (4.3.4.2)"},
9550         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9551         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9552         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9553         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9554         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9555         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9556         {0, NULL}
9557 };
9558
9559 /* values used by :
9560         TRANS2_QUERY_PATH_INFORMATION
9561         TRANS2_SET_PATH_INFORMATION
9562 */
9563 static const value_string qpi_loi_vals[] = {
9564         { 1,            "Info Standard  (4.2.14.1)"},
9565         { 2,            "Info Query EA Size  (4.2.14.1)"},
9566         { 3,            "Info Query EAs From List  (4.2.14.2)"},
9567         { 4,            "Info Query All EAs  (4.2.14.2)"},
9568         { 6,            "Info Is Name Valid  (4.2.14.3)"},
9569         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
9570         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
9571         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
9572         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
9573         { 0x0107,       "Query File All Info  (4.2.14.8)"},
9574         { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
9575         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
9576         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
9577         { 0x0200,       "Set File Unix Basic"},
9578         { 0x0201,       "Set File Unix Link"},
9579         { 0x0202,       "Set File Unix HardLink"},
9580         { 1004,         "Query File Basic Info  (4.2.14.4)"},
9581         { 1005,         "Query File Standard Info  (4.2.14.5)"},
9582         { 1006,         "Query File Internal Info  (4.2.14.?)"},
9583         { 1007,         "Query File EA Info  (4.2.14.6)"},
9584         { 1009,         "Query File Name Info  (4.2.14.7)"},
9585         { 1010,         "Query File Rename Info  (4.2.14.?)"},
9586         { 1011,         "Query File Link Info  (4.2.14.?)"},
9587         { 1012,         "Query File Names Info  (4.2.14.?)"},
9588         { 1013,         "Query File Disposition Info  (4.2.14.?)"},
9589         { 1014,         "Query File Position Info  (4.2.14.?)"},
9590         { 1015,         "Query File Full EA Info  (4.2.14.?)"},
9591         { 1016,         "Query File Mode Info  (4.2.14.?)"},
9592         { 1017,         "Query File Alignment Info  (4.2.14.?)"},
9593         { 1018,         "Query File All Info  (4.2.14.8)"},
9594         { 1019,         "Query File Allocation Info  (4.2.14.?)"},
9595         { 1020,         "Query File End of File Info  (4.2.14.?)"},
9596         { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
9597         { 1022,         "Query File Stream Info  (4.2.14.10)"},
9598         { 1023,         "Query File Pipe Info  (4.2.14.?)"},
9599         { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
9600         { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
9601         { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
9602         { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
9603         { 1028,         "Query File Compression Info  (4.2.14.11)"},
9604         { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
9605         { 1030,         "Query File Completion Info  (4.2.14.?)"},
9606         { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
9607         { 1032,         "Query File Quota Info  (4.2.14.?)"},
9608         { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
9609         { 1034,         "Query File Network Open Info  (4.2.14.?)"},
9610         { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
9611         { 1036,         "Query File Tracking Info  (4.2.14.?)"},
9612         { 1037,         "Query File Maximum Info  (4.2.14.?)"},
9613         {0, NULL}
9614 };
9615
9616 static const value_string qfsi_vals[] = {
9617         { 1,            "Info Allocation"},
9618         { 2,            "Info Volume"},
9619         { 0x0101,       "Query FS Label Info"},
9620         { 0x0102,       "Query FS Volume Info"},
9621         { 0x0103,       "Query FS Size Info"},
9622         { 0x0104,       "Query FS Device Info"},
9623         { 0x0105,       "Query FS Attribute Info"},
9624         { 0x0301,       "Mac Query FS INFO"},
9625         { 1001,         "Query FS Label Info"},
9626         { 1002,         "Query FS Volume Info"},
9627         { 1003,         "Query FS Size Info"},
9628         { 1004,         "Query FS Device Info"},
9629         { 1005,         "Query FS Attribute Info"},
9630         { 1006,         "Query FS Quota Info"},
9631         { 1007,         "Query Full FS Size Info"},
9632         {0, NULL}
9633 };
9634
9635 static const value_string nt_rename_vals[] = {
9636         { 0x0103,       "Create Hard Link"},
9637         {0, NULL}
9638 };
9639
9640
9641 static const value_string delete_pending_vals[] = {
9642         {0,     "Normal, no pending delete"},
9643         {1,     "This object has DELETE PENDING"},
9644         {0, NULL}
9645 };
9646
9647 static const value_string alignment_vals[] = {
9648         {0,     "Byte alignment"},
9649         {1,     "Word (16bit) alignment"},
9650         {3,     "Long (32bit) alignment"},
9651         {7,     "8 byte boundary alignment"},
9652         {0x0f,  "16 byte boundary alignment"},
9653         {0x1f,  "32 byte boundary alignment"},
9654         {0x3f,  "64 byte boundary alignment"},
9655         {0x7f,  "128 byte boundary alignment"},
9656         {0xff,  "256 byte boundary alignment"},
9657         {0x1ff, "512 byte boundary alignment"},
9658         {0, NULL}
9659 };
9660
9661
9662 static const true_false_string tfs_get_dfs_server_hold_storage = {
9663         "Referral SERVER HOLDS STORAGE for the file",
9664         "Referral server does NOT hold storage for the file"
9665 };
9666 static const true_false_string tfs_get_dfs_fielding = {
9667         "The server in referral is FIELDING CAPABLE",
9668         "The server in referrals is NOT fielding capable"
9669 };
9670
9671 static const true_false_string tfs_dfs_referral_flags_strip = {
9672         "STRIP off pathconsumed characters before submitting",
9673         "Do NOT strip off any characters"
9674 };
9675
9676 static const value_string dfs_referral_server_type_vals[] = {
9677         {0,     "Don't know"},
9678         {1,     "SMB Server"},
9679         {2,     "Netware Server"},
9680         {3,     "Domain Server"},
9681         {0, NULL}
9682 };
9683
9684
9685 static const true_false_string tfs_device_char_removable = {
9686         "This is a REMOVABLE device",
9687         "This is NOT a removable device"
9688 };
9689 static const true_false_string tfs_device_char_read_only = {
9690         "This is a READ-ONLY device",
9691         "This is NOT a read-only device"
9692 };
9693 static const true_false_string tfs_device_char_floppy = {
9694         "This is a FLOPPY DISK device",
9695         "This is NOT a floppy disk device"
9696 };
9697 static const true_false_string tfs_device_char_write_once = {
9698         "This is a WRITE-ONCE device",
9699         "This is NOT a write-once device"
9700 };
9701 static const true_false_string tfs_device_char_remote = {
9702         "This is a REMOTE device",
9703         "This is NOT a remote device"
9704 };
9705 static const true_false_string tfs_device_char_mounted = {
9706         "This device is MOUNTED",
9707         "This device is NOT mounted"
9708 };
9709 static const true_false_string tfs_device_char_virtual = {
9710         "This is a VIRTUAL device",
9711         "This is NOT a virtual device"
9712 };
9713
9714
9715 static const true_false_string tfs_fs_attr_css = {
9716         "This FS supports CASE SENSITIVE SEARCHes",
9717         "This FS does NOT support case sensitive searches"
9718 };
9719 static const true_false_string tfs_fs_attr_cpn = {
9720         "This FS supports CASE PRESERVED NAMES",
9721         "This FS does NOT support case preserved names"
9722 };
9723 static const true_false_string tfs_fs_attr_pacls = {
9724         "This FS supports PERSISTENT ACLs",
9725         "This FS does NOT support persistent acls"
9726 };
9727 static const true_false_string tfs_fs_attr_fc = {
9728         "This FS supports COMPRESSED FILES",
9729         "This FS does NOT support compressed files"
9730 };
9731 static const true_false_string tfs_fs_attr_vq = {
9732         "This FS supports VOLUME QUOTAS",
9733         "This FS does NOT support volume quotas"
9734 };
9735 static const true_false_string tfs_fs_attr_dim = {
9736         "This FS is on a MOUNTED DEVICE",
9737         "This FS is NOT on a mounted device"
9738 };
9739 static const true_false_string tfs_fs_attr_vic = {
9740         "This FS is on a COMPRESSED VOLUME",
9741         "This FS is NOT on a compressed volume"
9742 };
9743
9744 #define FF2_RESUME      0x0004
9745
9746 static int
9747 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9748 {
9749         guint16 mask;
9750         proto_item *item = NULL;
9751         proto_tree *tree = NULL;
9752         smb_info_t *si;
9753         smb_transact2_info_t *t2i;
9754
9755         mask = tvb_get_letohs(tvb, offset);
9756
9757         si = (smb_info_t *)pinfo->private_data;
9758         if (si->sip != NULL) {
9759                 t2i = si->sip->extra_info;
9760                 if (t2i != NULL) {
9761                         if (!pinfo->fd->flags.visited)
9762                                 t2i->resume_keys = (mask & FF2_RESUME);
9763                 }
9764         }
9765
9766         if(parent_tree){
9767                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9768                         "Flags: 0x%04x", mask);
9769                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9770         }
9771
9772         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9773                 tvb, offset, 2, mask);
9774         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9775                 tvb, offset, 2, mask);
9776         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9777                 tvb, offset, 2, mask);
9778         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9779                 tvb, offset, 2, mask);
9780         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9781                 tvb, offset, 2, mask);
9782
9783         offset += 2;
9784
9785         return offset;
9786 }
9787
9788 #if 0
9789 static int
9790 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9791 {
9792         guint16 mask;
9793         proto_item *item = NULL;
9794         proto_tree *tree = NULL;
9795
9796         mask = tvb_get_letohs(tvb, offset);
9797
9798         if(parent_tree){
9799                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9800                         "IO Flag: 0x%04x", mask);
9801                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9802         }
9803
9804         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9805                 tvb, offset, 2, mask);
9806         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9807                 tvb, offset, 2, mask);
9808
9809         offset += 2;
9810
9811         return offset;
9812 }
9813 #endif
9814
9815 static int
9816 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9817     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9818 {
9819         proto_item *item = NULL;
9820         proto_tree *tree = NULL;
9821         smb_info_t *si;
9822         smb_transact2_info_t *t2i;
9823         int fn_len;
9824         const char *fn;
9825         int old_offset = offset;
9826
9827         si = (smb_info_t *)pinfo->private_data;
9828         if (si->sip != NULL)
9829                 t2i = si->sip->extra_info;
9830         else
9831                 t2i = NULL;
9832
9833         if(parent_tree){
9834                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9835                                 "%s Parameters",
9836                                 val_to_str(subcmd, trans2_cmd_vals,
9837                                            "Unknown (0x%02x)"));
9838                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9839         }
9840
9841         switch(subcmd){
9842         case 0x00:      /*TRANS2_OPEN2*/
9843                 /* open flags */
9844                 CHECK_BYTE_COUNT_TRANS(2);
9845                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9846                 bc -= 2;
9847
9848                 /* desired access */
9849                 CHECK_BYTE_COUNT_TRANS(2);
9850                 offset = dissect_access(tvb, tree, offset, "Desired");
9851                 bc -= 2;
9852
9853                 /* Search Attributes */
9854                 CHECK_BYTE_COUNT_TRANS(2);
9855                 offset = dissect_search_attributes(tvb, tree, offset);
9856                 bc -= 2;
9857
9858                 /* File Attributes */
9859                 CHECK_BYTE_COUNT_TRANS(2);
9860                 offset = dissect_file_attributes(tvb, tree, offset, 2);
9861                 bc -= 2;
9862
9863                 /* create time */
9864                 CHECK_BYTE_COUNT_TRANS(4);
9865                 offset = dissect_smb_datetime(tvb, tree, offset,
9866                         hf_smb_create_time,
9867                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9868                         TRUE);
9869                 bc -= 4;
9870
9871                 /* open function */
9872                 CHECK_BYTE_COUNT_TRANS(2);
9873                 offset = dissect_open_function(tvb, tree, offset);
9874                 bc -= 2;
9875
9876                 /* allocation size */
9877                 CHECK_BYTE_COUNT_TRANS(4);
9878                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9879                 COUNT_BYTES_TRANS(4);
9880
9881                 /* 10 reserved bytes */
9882                 CHECK_BYTE_COUNT_TRANS(10);
9883                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9884                 COUNT_BYTES_TRANS(10);
9885
9886                 /* file name */
9887                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9888                 CHECK_STRING_TRANS(fn);
9889                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9890                         fn);
9891                 COUNT_BYTES_TRANS(fn_len);
9892
9893                 if (check_col(pinfo->cinfo, COL_INFO)) {
9894                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9895                         fn);
9896                 }
9897                 break;
9898         case 0x01:      /*TRANS2_FIND_FIRST2*/
9899                 /* Search Attributes */
9900                 CHECK_BYTE_COUNT_TRANS(2);
9901                 offset = dissect_search_attributes(tvb, tree, offset);
9902                 bc -= 2;
9903
9904                 /* search count */
9905                 CHECK_BYTE_COUNT_TRANS(2);
9906                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9907                 COUNT_BYTES_TRANS(2);
9908
9909                 /* Find First2 flags */
9910                 CHECK_BYTE_COUNT_TRANS(2);
9911                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9912                 bc -= 2;
9913
9914                 /* Find First2 information level */
9915                 CHECK_BYTE_COUNT_TRANS(2);
9916                 si->info_level = tvb_get_letohs(tvb, offset);
9917                 if (!pinfo->fd->flags.visited)
9918                         t2i->info_level = si->info_level;
9919                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9920                 COUNT_BYTES_TRANS(2);
9921
9922                 /* storage type */
9923                 CHECK_BYTE_COUNT_TRANS(4);
9924                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9925                 COUNT_BYTES_TRANS(4);
9926
9927                 /* search pattern */
9928                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9929                 CHECK_STRING_TRANS(fn);
9930                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9931                         fn);
9932                 COUNT_BYTES_TRANS(fn_len);
9933
9934                 if (check_col(pinfo->cinfo, COL_INFO)) {
9935                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9936                         fn);
9937                 }
9938
9939                 break;
9940         case 0x02:      /*TRANS2_FIND_NEXT2*/
9941                 /* sid */
9942                 CHECK_BYTE_COUNT_TRANS(2);
9943                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
9944                 COUNT_BYTES_TRANS(2);
9945
9946                 /* search count */
9947                 CHECK_BYTE_COUNT_TRANS(2);
9948                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9949                 COUNT_BYTES_TRANS(2);
9950
9951                 /* Find First2 information level */
9952                 CHECK_BYTE_COUNT_TRANS(2);
9953                 si->info_level = tvb_get_letohs(tvb, offset);
9954                 if (!pinfo->fd->flags.visited)
9955                         t2i->info_level = si->info_level;
9956                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9957                 COUNT_BYTES_TRANS(2);
9958
9959                 /* resume key */
9960                 CHECK_BYTE_COUNT_TRANS(4);
9961                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9962                 COUNT_BYTES_TRANS(4);
9963
9964                 /* Find First2 flags */
9965                 CHECK_BYTE_COUNT_TRANS(2);
9966                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9967                 bc -= 2;
9968
9969                 /* file name */
9970                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9971                 CHECK_STRING_TRANS(fn);
9972                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9973                         fn);
9974                 COUNT_BYTES_TRANS(fn_len);
9975
9976                 if (check_col(pinfo->cinfo, COL_INFO)) {
9977                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9978                         fn);
9979                 }
9980
9981                 break;
9982         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9983                 /* level of interest */
9984                 CHECK_BYTE_COUNT_TRANS(2);
9985                 si->info_level = tvb_get_letohs(tvb, offset);
9986                 if (!pinfo->fd->flags.visited)
9987                         t2i->info_level = si->info_level;
9988                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9989                 COUNT_BYTES_TRANS(2);
9990
9991                 break;
9992         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9993                 /* level of interest */
9994                 CHECK_BYTE_COUNT_TRANS(2);
9995                 si->info_level = tvb_get_letohs(tvb, offset);
9996                 if (!pinfo->fd->flags.visited)
9997                         t2i->info_level = si->info_level;
9998                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9999                 COUNT_BYTES_TRANS(2);
10000
10001                 /* 4 reserved bytes */
10002                 CHECK_BYTE_COUNT_TRANS(4);
10003                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10004                 COUNT_BYTES_TRANS(4);
10005
10006                 /* file name */
10007                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10008                 CHECK_STRING_TRANS(fn);
10009                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10010                         fn);
10011                 COUNT_BYTES_TRANS(fn_len);
10012
10013                 if (check_col(pinfo->cinfo, COL_INFO)) {
10014                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10015                         fn);
10016                 }
10017
10018                 break;
10019         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10020                 /* level of interest */
10021                 CHECK_BYTE_COUNT_TRANS(2);
10022                 si->info_level = tvb_get_letohs(tvb, offset);
10023                 if (!pinfo->fd->flags.visited)
10024                         t2i->info_level = si->info_level;
10025                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10026                 COUNT_BYTES_TRANS(2);
10027
10028                 /* 4 reserved bytes */
10029                 CHECK_BYTE_COUNT_TRANS(4);
10030                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10031                 COUNT_BYTES_TRANS(4);
10032
10033                 /* file name */
10034                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10035                 CHECK_STRING_TRANS(fn);
10036                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10037                         fn);
10038                 COUNT_BYTES_TRANS(fn_len);
10039
10040                 if (check_col(pinfo->cinfo, COL_INFO)) {
10041                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10042                         fn);
10043                 }
10044
10045                 break;
10046         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10047                 guint16 fid;
10048
10049                 /* fid */
10050                 CHECK_BYTE_COUNT_TRANS(2);
10051                 fid = tvb_get_letohs(tvb, offset);
10052                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10053                 COUNT_BYTES_TRANS(2);
10054
10055                 /* level of interest */
10056                 CHECK_BYTE_COUNT_TRANS(2);
10057                 si->info_level = tvb_get_letohs(tvb, offset);
10058                 if (!pinfo->fd->flags.visited)
10059                         t2i->info_level = si->info_level;
10060                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10061                 COUNT_BYTES_TRANS(2);
10062
10063                 break;
10064         }
10065         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10066                 guint16 fid;
10067
10068                 /* fid */
10069                 CHECK_BYTE_COUNT_TRANS(2);
10070                 fid = tvb_get_letohs(tvb, offset);
10071                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10072                 COUNT_BYTES_TRANS(2);
10073
10074                 /* level of interest */
10075                 CHECK_BYTE_COUNT_TRANS(2);
10076                 si->info_level = tvb_get_letohs(tvb, offset);
10077                 if (!pinfo->fd->flags.visited)
10078                         t2i->info_level = si->info_level;
10079                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10080                 COUNT_BYTES_TRANS(2);
10081
10082 #if 0
10083                 /*
10084                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10085                  * Extensions Version 3.0, Document Version 1.11,
10086                  * July 19, 1990" says this is I/O flags, but it's
10087                  * reserved in the SNIA spec, and some clients appear
10088                  * to leave junk in it.
10089                  *
10090                  * Is this some field used only if a particular
10091                  * dialect was negotiated, so that clients can feel
10092                  * safe not setting it if they haven't negotiated that
10093                  * dialect?  Or do the (non-OS/2) clients simply not care
10094                  * about that particular OS/2-oriented dialect?
10095                  */
10096
10097                 /* IO Flag */
10098                 CHECK_BYTE_COUNT_TRANS(2);
10099                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10100                 bc -= 2;
10101 #else
10102                 /* 2 reserved bytes */
10103                 CHECK_BYTE_COUNT_TRANS(2);
10104                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10105                 COUNT_BYTES_TRANS(2);
10106 #endif
10107
10108                 break;
10109         }
10110         case 0x09:      /*TRANS2_FSCTL*/
10111                 /* this call has no parameter block in the request */
10112
10113                 /*
10114                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10115                  * Extensions Version 3.0, Document Version 1.11,
10116                  * July 19, 1990" says this this contains a
10117                  * "File system specific parameter block".  (That means
10118                  * we may not be able to dissect it in any case.)
10119                  */
10120                 break;
10121         case 0x0a:      /*TRANS2_IOCTL2*/
10122                 /* this call has no parameter block in the request */
10123
10124                 /*
10125                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10126                  * Extensions Version 3.0, Document Version 1.11,
10127                  * July 19, 1990" says this this contains a
10128                  * "Device/function specific parameter block".  (That
10129                  * means we may not be able to dissect it in any case.)
10130                  */
10131                 break;
10132         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10133                 /* Search Attributes */
10134                 CHECK_BYTE_COUNT_TRANS(2);
10135                 offset = dissect_search_attributes(tvb, tree, offset);
10136                 bc -= 2;
10137
10138                 /* Number of changes to wait for */
10139                 CHECK_BYTE_COUNT_TRANS(2);
10140                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10141                 COUNT_BYTES_TRANS(2);
10142
10143                 /* Find Notify information level */
10144                 CHECK_BYTE_COUNT_TRANS(2);
10145                 si->info_level = tvb_get_letohs(tvb, offset);
10146                 if (!pinfo->fd->flags.visited)
10147                         t2i->info_level = si->info_level;
10148                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10149                 COUNT_BYTES_TRANS(2);
10150
10151                 /* 4 reserved bytes */
10152                 CHECK_BYTE_COUNT_TRANS(4);
10153                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10154                 COUNT_BYTES_TRANS(4);
10155
10156                 /* file name */
10157                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10158                 CHECK_STRING_TRANS(fn);
10159                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10160                         fn);
10161                 COUNT_BYTES_TRANS(fn_len);
10162
10163                 if (check_col(pinfo->cinfo, COL_INFO)) {
10164                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10165                         fn);
10166                 }
10167
10168                 break;
10169         }
10170         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10171                 /* Monitor handle */
10172                 CHECK_BYTE_COUNT_TRANS(2);
10173                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10174                 COUNT_BYTES_TRANS(2);
10175
10176                 /* Number of changes to wait for */
10177                 CHECK_BYTE_COUNT_TRANS(2);
10178                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10179                 COUNT_BYTES_TRANS(2);
10180
10181                 break;
10182         }
10183         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10184                 /* 4 reserved bytes */
10185                 CHECK_BYTE_COUNT_TRANS(4);
10186                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10187                 COUNT_BYTES_TRANS(4);
10188
10189                 /* dir name */
10190                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10191                         FALSE, FALSE, &bc);
10192                 CHECK_STRING_TRANS(fn);
10193                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10194                         fn);
10195                 COUNT_BYTES_TRANS(fn_len);
10196
10197                 if (check_col(pinfo->cinfo, COL_INFO)) {
10198                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10199                         fn);
10200                 }
10201                 break;
10202         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10203                 /* XXX unknown structure*/
10204                 break;
10205         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10206                 /* referral level */
10207                 CHECK_BYTE_COUNT_TRANS(2);
10208                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10209                 COUNT_BYTES_TRANS(2);
10210
10211                 /* file name */
10212                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10213                 CHECK_STRING_TRANS(fn);
10214                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10215                         fn);
10216                 COUNT_BYTES_TRANS(fn_len);
10217
10218                 if (check_col(pinfo->cinfo, COL_INFO)) {
10219                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10220                         fn);
10221                 }
10222
10223                 break;
10224         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10225                 /* file name */
10226                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10227                 CHECK_STRING_TRANS(fn);
10228                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10229                         fn);
10230                 COUNT_BYTES_TRANS(fn_len);
10231
10232                 if (check_col(pinfo->cinfo, COL_INFO)) {
10233                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10234                         fn);
10235                 }
10236
10237                 break;
10238         }
10239
10240         /* ooops there were data we didnt know how to process */
10241         if((offset-old_offset) < bc){
10242                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
10243                     bc - (offset-old_offset), TRUE);
10244                 offset += bc - (offset-old_offset);
10245         }
10246
10247         return offset;
10248 }
10249
10250 /*
10251  * XXX - just use "dissect_connect_flags()" here?
10252  */
10253 static guint16
10254 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10255 {
10256         guint16 mask;
10257         proto_item *item = NULL;
10258         proto_tree *tree = NULL;
10259
10260         mask = tvb_get_letohs(tvb, offset);
10261
10262         if(parent_tree){
10263                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10264                         "Flags: 0x%04x", mask);
10265                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10266         }
10267
10268         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10269                 tvb, offset, 2, mask);
10270         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10271                 tvb, offset, 2, mask);
10272
10273         return mask;
10274 }
10275
10276
10277 static int
10278 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10279 {
10280         guint16 mask;
10281         proto_item *item = NULL;
10282         proto_tree *tree = NULL;
10283
10284         mask = tvb_get_letohs(tvb, offset);
10285
10286         if(parent_tree){
10287                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10288                         "Flags: 0x%04x", mask);
10289                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10290         }
10291
10292         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10293                 tvb, offset, 2, mask);
10294         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10295                 tvb, offset, 2, mask);
10296
10297         offset += 2;
10298         return offset;
10299 }
10300
10301 static int
10302 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10303 {
10304         guint16 mask;
10305         proto_item *item = NULL;
10306         proto_tree *tree = NULL;
10307
10308         mask = tvb_get_letohs(tvb, offset);
10309
10310         if(parent_tree){
10311                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10312                         "Flags: 0x%04x", mask);
10313                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10314         }
10315
10316         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10317                 tvb, offset, 2, mask);
10318
10319         offset += 2;
10320
10321         return offset;
10322 }
10323
10324
10325 /* dfs inconsistency data  (4.4.2)
10326 */
10327 static int
10328 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10329     proto_tree *tree, int offset, guint16 *bcp)
10330 {
10331         smb_info_t *si = pinfo->private_data;
10332         int fn_len;
10333         const char *fn;
10334
10335         /*XXX shouldn this data hold version and size? unclear from doc*/
10336         /* referral version */
10337         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10338         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10339         COUNT_BYTES_TRANS_SUBR(2);
10340
10341         /* referral size */
10342         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10343         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10344         COUNT_BYTES_TRANS_SUBR(2);
10345
10346         /* referral server type */
10347         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10348         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10349         COUNT_BYTES_TRANS_SUBR(2);
10350
10351         /* referral flags */
10352         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10353         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10354         *bcp -= 2;
10355
10356         /* node name */
10357         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10358         CHECK_STRING_TRANS_SUBR(fn);
10359         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10360                 fn);
10361         COUNT_BYTES_TRANS_SUBR(fn_len);
10362
10363         return offset;
10364 }
10365
10366 /* get dfs referral data  (4.4.1)
10367 */
10368 static int
10369 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10370     proto_tree *tree, int offset, guint16 *bcp)
10371 {
10372         smb_info_t *si = pinfo->private_data;
10373         guint16 numref;
10374         guint16 refsize;
10375         guint16 pathoffset;
10376         guint16 altpathoffset;
10377         guint16 nodeoffset;
10378         int fn_len;
10379         int stroffset;
10380         int offsetoffset;
10381         guint16 save_bc;
10382         const char *fn;
10383         int unklen;
10384         int ucstring_end;
10385         int ucstring_len;
10386
10387         /* path consumed */
10388         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10389         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10390         COUNT_BYTES_TRANS_SUBR(2);
10391
10392         /* num referrals */
10393         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10394         numref = tvb_get_letohs(tvb, offset);
10395         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10396         COUNT_BYTES_TRANS_SUBR(2);
10397
10398         /* get dfs flags */
10399         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10400         offset = dissect_get_dfs_flags(tvb, tree, offset);
10401         *bcp -= 2;
10402
10403         /* XXX - in at least one capture there appears to be 2 bytes
10404            of stuff after the Dfs flags, perhaps so that the header
10405            in front of the referral list is a multiple of 4 bytes long. */
10406         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10407         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10408         COUNT_BYTES_TRANS_SUBR(2);
10409
10410         /* if there are any referrals */
10411         if(numref){
10412                 proto_item *ref_item = NULL;
10413                 proto_tree *ref_tree = NULL;
10414                 int old_offset=offset;
10415
10416                 if(tree){
10417                         ref_item = proto_tree_add_text(tree,
10418                                 tvb, offset, *bcp, "Referrals");
10419                         ref_tree = proto_item_add_subtree(ref_item,
10420                                 ett_smb_dfs_referrals);
10421                 }
10422                 ucstring_end = -1;
10423
10424                 while(numref--){
10425                         proto_item *ri = NULL;
10426                         proto_tree *rt = NULL;
10427                         int old_offset=offset;
10428                         guint16 version;
10429
10430                         if(tree){
10431                                 ri = proto_tree_add_text(ref_tree,
10432                                         tvb, offset, *bcp, "Referral");
10433                                 rt = proto_item_add_subtree(ri,
10434                                         ett_smb_dfs_referral);
10435                         }
10436
10437                         /* referral version */
10438                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10439                         version = tvb_get_letohs(tvb, offset);
10440                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10441                                 tvb, offset, 2, version);
10442                         COUNT_BYTES_TRANS_SUBR(2);
10443
10444                         /* referral size */
10445                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10446                         refsize = tvb_get_letohs(tvb, offset);
10447                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10448                         COUNT_BYTES_TRANS_SUBR(2);
10449
10450                         /* referral server type */
10451                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10452                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10453                         COUNT_BYTES_TRANS_SUBR(2);
10454
10455                         /* referral flags */
10456                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10457                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10458                         *bcp -= 2;
10459
10460                         switch(version){
10461
10462                         case 1:
10463                                 /* node name */
10464                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10465                                 CHECK_STRING_TRANS_SUBR(fn);
10466                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10467                                         fn);
10468                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10469                                 break;
10470
10471                         case 2:
10472                         case 3: /* XXX - like version 2, but not identical;
10473                                    seen in a capture, but the format isn't
10474                                    documented */
10475                                 /* proximity */
10476                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10477                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10478                                 COUNT_BYTES_TRANS_SUBR(2);
10479
10480                                 /* ttl */
10481                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10482                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10483                                 COUNT_BYTES_TRANS_SUBR(2);
10484
10485                                 /* path offset */
10486                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10487                                 pathoffset = tvb_get_letohs(tvb, offset);
10488                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10489                                 COUNT_BYTES_TRANS_SUBR(2);
10490
10491                                 /* alt path offset */
10492                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10493                                 altpathoffset = tvb_get_letohs(tvb, offset);
10494                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10495                                 COUNT_BYTES_TRANS_SUBR(2);
10496
10497                                 /* node offset */
10498                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10499                                 nodeoffset = tvb_get_letohs(tvb, offset);
10500                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10501                                 COUNT_BYTES_TRANS_SUBR(2);
10502
10503                                 /* path */
10504                                 if (pathoffset != 0) {
10505                                         stroffset = old_offset + pathoffset;
10506                                         offsetoffset = stroffset - offset;
10507                                         if (offsetoffset > 0 &&
10508                                             *bcp > offsetoffset) {
10509                                                 save_bc = *bcp;
10510                                                 *bcp -= offsetoffset;
10511                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10512                                                 CHECK_STRING_TRANS_SUBR(fn);
10513                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10514                                                         fn);
10515                                                 stroffset += fn_len;
10516                                                 if (ucstring_end < stroffset)
10517                                                         ucstring_end = stroffset;
10518                                                 *bcp = save_bc;
10519                                         }
10520                                 }
10521
10522                                 /* alt path */
10523                                 if (altpathoffset != 0) {
10524                                         stroffset = old_offset + altpathoffset;
10525                                         offsetoffset = stroffset - offset;
10526                                         if (offsetoffset > 0 &&
10527                                             *bcp > offsetoffset) {
10528                                                 save_bc = *bcp;
10529                                                 *bcp -= offsetoffset;
10530                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10531                                                 CHECK_STRING_TRANS_SUBR(fn);
10532                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10533                                                         fn);
10534                                                 stroffset += fn_len;
10535                                                 if (ucstring_end < stroffset)
10536                                                         ucstring_end = stroffset;
10537                                                 *bcp = save_bc;
10538                                         }
10539                                 }
10540
10541                                 /* node */
10542                                 if (nodeoffset != 0) {
10543                                         stroffset = old_offset + nodeoffset;
10544                                         offsetoffset = stroffset - offset;
10545                                         if (offsetoffset > 0 &&
10546                                             *bcp > offsetoffset) {
10547                                                 save_bc = *bcp;
10548                                                 *bcp -= offsetoffset;
10549                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10550                                                 CHECK_STRING_TRANS_SUBR(fn);
10551                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10552                                                         fn);
10553                                                 stroffset += fn_len;
10554                                                 if (ucstring_end < stroffset)
10555                                                         ucstring_end = stroffset;
10556                                                 *bcp = save_bc;
10557                                         }
10558                                 }
10559                                 break;
10560                         }
10561
10562                         /*
10563                          * Show anything beyond the length of the referral
10564                          * as unknown data.
10565                          */
10566                         unklen = (old_offset + refsize) - offset;
10567                         if (unklen < 0) {
10568                                 /*
10569                                  * XXX - the length is bogus.
10570                                  */
10571                                 unklen = 0;
10572                         }
10573                         if (unklen != 0) {
10574                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10575                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10576                                     offset, unklen, TRUE);
10577                                 COUNT_BYTES_TRANS_SUBR(unklen);
10578                         }
10579
10580                         proto_item_set_len(ri, offset-old_offset);
10581                 }
10582
10583                 /*
10584                  * Treat the offset past the end of the last Unicode
10585                  * string after the referrals (if any) as the last
10586                  * offset.
10587                  */
10588                 if (ucstring_end > offset) {
10589                         ucstring_len = ucstring_end - offset;
10590                         if (*bcp < ucstring_len)
10591                                 ucstring_len = *bcp;
10592                         offset += ucstring_len;
10593                         *bcp -= ucstring_len;
10594                 }
10595                 proto_item_set_len(ref_item, offset-old_offset);
10596         }
10597
10598         return offset;
10599 }
10600
10601
10602 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10603    as described in 4.2.14.1
10604 */
10605 static int
10606 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10607     int offset, guint16 *bcp, gboolean *trunc)
10608 {
10609         /* create time */
10610         CHECK_BYTE_COUNT_SUBR(4);
10611         offset = dissect_smb_datetime(tvb, tree, offset,
10612                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10613                 FALSE);
10614         *bcp -= 4;
10615
10616         /* access time */
10617         CHECK_BYTE_COUNT_SUBR(4);
10618         offset = dissect_smb_datetime(tvb, tree, offset,
10619                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10620                 FALSE);
10621         *bcp -= 4;
10622
10623         /* last write time */
10624         CHECK_BYTE_COUNT_SUBR(4);
10625         offset = dissect_smb_datetime(tvb, tree, offset,
10626                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10627                 FALSE);
10628         *bcp -= 4;
10629
10630         /* data size */
10631         CHECK_BYTE_COUNT_SUBR(4);
10632         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10633         COUNT_BYTES_SUBR(4);
10634
10635         /* allocation size */
10636         CHECK_BYTE_COUNT_SUBR(4);
10637         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10638         COUNT_BYTES_SUBR(4);
10639
10640         /* File Attributes */
10641         CHECK_BYTE_COUNT_SUBR(2);
10642         offset = dissect_file_attributes(tvb, tree, offset, 2);
10643         *bcp -= 2;
10644
10645         /* ea size */
10646         CHECK_BYTE_COUNT_SUBR(4);
10647         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10648         COUNT_BYTES_SUBR(4);
10649
10650         *trunc = FALSE;
10651         return offset;
10652 }
10653
10654 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10655    as described in 4.2.14.2
10656 */
10657 static int
10658 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10659     int offset, guint16 *bcp, gboolean *trunc)
10660 {
10661         /* list length */
10662         CHECK_BYTE_COUNT_SUBR(4);
10663         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
10664         COUNT_BYTES_SUBR(4);
10665
10666         *trunc = FALSE;
10667         return offset;
10668 }
10669
10670 /* this dissects the SMB_INFO_IS_NAME_VALID
10671    as described in 4.2.14.3
10672 */
10673 static int
10674 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10675     int offset, guint16 *bcp, gboolean *trunc)
10676 {
10677         smb_info_t *si = pinfo->private_data;
10678         int fn_len;
10679         const char *fn;
10680
10681         /* file name */
10682         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10683         CHECK_STRING_SUBR(fn);
10684         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10685                 fn);
10686         COUNT_BYTES_SUBR(fn_len);
10687
10688         *trunc = FALSE;
10689         return offset;
10690 }
10691
10692 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10693    as described in 4.2.14.4
10694 */
10695 static int
10696 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10697     int offset, guint16 *bcp, gboolean *trunc)
10698 {
10699         /* create time */
10700         CHECK_BYTE_COUNT_SUBR(8);
10701         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10702         *bcp -= 8;
10703
10704         /* access time */
10705         CHECK_BYTE_COUNT_SUBR(8);
10706         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10707         *bcp -= 8;
10708
10709         /* last write time */
10710         CHECK_BYTE_COUNT_SUBR(8);
10711         offset = dissect_smb_64bit_time(tvb, tree, offset,
10712                 hf_smb_last_write_time);
10713         *bcp -= 8;
10714
10715         /* last change time */
10716         CHECK_BYTE_COUNT_SUBR(8);
10717         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10718         *bcp -= 8;
10719
10720         /* File Attributes */
10721         CHECK_BYTE_COUNT_SUBR(4);
10722         offset = dissect_file_attributes(tvb, tree, offset, 4);
10723         *bcp -= 4;
10724
10725         *trunc = FALSE;
10726         return offset;
10727 }
10728
10729 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10730    as described in 4.2.14.5
10731 */
10732 static int
10733 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10734     int offset, guint16 *bcp, gboolean *trunc)
10735 {
10736         /* allocation size */
10737         CHECK_BYTE_COUNT_SUBR(8);
10738         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10739         COUNT_BYTES_SUBR(8);
10740
10741         /* end of file */
10742         CHECK_BYTE_COUNT_SUBR(8);
10743         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10744         COUNT_BYTES_SUBR(8);
10745
10746         /* number of links */
10747         CHECK_BYTE_COUNT_SUBR(4);
10748         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10749         COUNT_BYTES_SUBR(4);
10750
10751         /* delete pending */
10752         CHECK_BYTE_COUNT_SUBR(1);
10753         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
10754         COUNT_BYTES_SUBR(1);
10755
10756         /* is directory */
10757         CHECK_BYTE_COUNT_SUBR(1);
10758         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10759         COUNT_BYTES_SUBR(1);
10760
10761         *trunc = FALSE;
10762         return offset;
10763 }
10764
10765 /* this dissects the SMB_QUERY_FILE_EA_INFO
10766    as described in 4.2.14.6
10767 */
10768 static int
10769 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10770     int offset, guint16 *bcp, gboolean *trunc)
10771 {
10772         /* ea size */
10773         CHECK_BYTE_COUNT_SUBR(4);
10774         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10775         COUNT_BYTES_SUBR(4);
10776
10777         *trunc = FALSE;
10778         return offset;
10779 }
10780
10781 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10782    as described in 4.2.14.7
10783    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10784    as described in 4.2.14.9
10785 */
10786 static int
10787 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10788     int offset, guint16 *bcp, gboolean *trunc)
10789 {
10790         smb_info_t *si = pinfo->private_data;
10791         int fn_len;
10792         const char *fn;
10793
10794         /* file name len */
10795         CHECK_BYTE_COUNT_SUBR(4);
10796         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10797         COUNT_BYTES_SUBR(4);
10798
10799         /* file name */
10800         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10801         CHECK_STRING_SUBR(fn);
10802         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10803                 fn);
10804         COUNT_BYTES_SUBR(fn_len);
10805
10806         *trunc = FALSE;
10807         return offset;
10808 }
10809
10810 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10811    as described in 4.2.14.8
10812 */
10813 static int
10814 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10815     int offset, guint16 *bcp, gboolean *trunc)
10816 {
10817
10818         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
10819         if (*trunc) {
10820                 return offset;
10821         }
10822         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
10823         if (*trunc) {
10824                 return offset;
10825         }
10826
10827         /* index number */
10828         CHECK_BYTE_COUNT_SUBR(8);
10829         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10830         COUNT_BYTES_SUBR(8);
10831
10832         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10833         if (*trunc)
10834                 return offset;
10835
10836         /* access flags */
10837         CHECK_BYTE_COUNT_SUBR(4);
10838         offset = dissect_smb_access_mask(tvb, tree, offset);
10839         COUNT_BYTES_SUBR(4);
10840
10841         /* index number */
10842         CHECK_BYTE_COUNT_SUBR(8);
10843         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10844         COUNT_BYTES_SUBR(8);
10845
10846         /* current offset */
10847         CHECK_BYTE_COUNT_SUBR(8);
10848         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10849         COUNT_BYTES_SUBR(8);
10850
10851         /* mode */
10852         CHECK_BYTE_COUNT_SUBR(4);
10853         offset = dissect_nt_create_options(tvb, tree, offset);
10854         *bcp -= 4;
10855
10856         /* alignment */
10857         CHECK_BYTE_COUNT_SUBR(4);
10858         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10859         COUNT_BYTES_SUBR(4);
10860
10861         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10862
10863         return offset;
10864 }
10865
10866 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10867    as described in 4.2.14.10
10868 */
10869 static int
10870 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10871     int offset, guint16 *bcp, gboolean *trunc)
10872 {
10873         proto_item *item;
10874         proto_tree *tree;
10875         int old_offset;
10876         guint32 neo;
10877         smb_info_t *si = pinfo->private_data;
10878         int fn_len;
10879         const char *fn;
10880         int padcnt;
10881
10882         for (;;) {
10883                 old_offset = offset;
10884
10885                 /* next entry offset */
10886                 CHECK_BYTE_COUNT_SUBR(4);
10887                 if(parent_tree){
10888                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10889                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10890                 } else {
10891                         item = NULL;
10892                         tree = NULL;
10893                 }
10894
10895                 neo = tvb_get_letohl(tvb, offset);
10896                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10897                 COUNT_BYTES_SUBR(4);
10898
10899                 /* stream name len */
10900                 CHECK_BYTE_COUNT_SUBR(4);
10901                 fn_len = tvb_get_letohl(tvb, offset);
10902                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10903                 COUNT_BYTES_SUBR(4);
10904
10905                 /* stream size */
10906                 CHECK_BYTE_COUNT_SUBR(8);
10907                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10908                 COUNT_BYTES_SUBR(8);
10909
10910                 /* allocation size */
10911                 CHECK_BYTE_COUNT_SUBR(8);
10912                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10913                 COUNT_BYTES_SUBR(8);
10914
10915                 /* stream name */
10916                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10917                 CHECK_STRING_SUBR(fn);
10918                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10919                         fn);
10920                 COUNT_BYTES_SUBR(fn_len);
10921
10922                 proto_item_append_text(item, ": %s", fn);
10923                 proto_item_set_len(item, offset-old_offset);
10924
10925                 if (neo == 0)
10926                         break;  /* no more structures */
10927
10928                 /* skip to next structure */
10929                 padcnt = (old_offset + neo) - offset;
10930                 if (padcnt < 0) {
10931                         /*
10932                          * XXX - this is bogus; flag it?
10933                          */
10934                         padcnt = 0;
10935                 }
10936                 if (padcnt != 0) {
10937                         CHECK_BYTE_COUNT_SUBR(padcnt);
10938                         COUNT_BYTES_SUBR(padcnt);
10939                 }
10940         }
10941
10942         *trunc = FALSE;
10943         return offset;
10944 }
10945
10946 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10947    as described in 4.2.14.11
10948 */
10949 static int
10950 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10951     int offset, guint16 *bcp, gboolean *trunc)
10952 {
10953         /* compressed file size */
10954         CHECK_BYTE_COUNT_SUBR(8);
10955         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10956         COUNT_BYTES_SUBR(8);
10957
10958         /* compression format */
10959         CHECK_BYTE_COUNT_SUBR(2);
10960         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10961         COUNT_BYTES_SUBR(2);
10962
10963         /* compression unit shift */
10964         CHECK_BYTE_COUNT_SUBR(1);
10965         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10966         COUNT_BYTES_SUBR(1);
10967
10968         /* compression chunk shift */
10969         CHECK_BYTE_COUNT_SUBR(1);
10970         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10971         COUNT_BYTES_SUBR(1);
10972
10973         /* compression cluster shift */
10974         CHECK_BYTE_COUNT_SUBR(1);
10975         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10976         COUNT_BYTES_SUBR(1);
10977
10978         /* 3 reserved bytes */
10979         CHECK_BYTE_COUNT_SUBR(3);
10980         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10981         COUNT_BYTES_SUBR(3);
10982
10983         *trunc = FALSE;
10984         return offset;
10985 }
10986
10987
10988
10989 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
10990 static int
10991 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10992     int offset, guint16 *bcp)
10993 {
10994         smb_info_t *si;
10995         gboolean trunc;
10996
10997         if(!*bcp){
10998                 return offset;
10999         }
11000
11001         si = (smb_info_t *)pinfo->private_data;
11002         switch(si->info_level){
11003         case 1:         /*Info Standard*/
11004         case 2:         /*Info Query EA Size*/
11005                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
11006                     &trunc);
11007                 break;
11008         case 3:         /*Info Query EAs From List*/
11009         case 4:         /*Info Query All EAs*/
11010                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
11011                     &trunc);
11012                 break;
11013         case 6:         /*Info Is Name Valid*/
11014                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
11015                     &trunc);
11016                 break;
11017         case 0x0101:    /*Query File Basic Info*/
11018         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11019                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
11020                     &trunc);
11021                 break;
11022         case 0x0102:    /*Query File Standard Info*/
11023         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11024                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
11025                     &trunc);
11026                 break;
11027         case 0x0103:    /*Query File EA Info*/
11028         case 1007:      /* SMB_FILE_EA_INFORMATION */
11029                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
11030                     &trunc);
11031                 break;
11032         case 0x0104:    /*Query File Name Info*/
11033         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11034                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
11035                     &trunc);
11036                 break;
11037         case 0x0107:    /*Query File All Info*/
11038         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11039                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
11040                     &trunc);
11041                 break;
11042         case 0x0108:    /*Query File Alt File Info*/
11043         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11044                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
11045                     &trunc);
11046                 break;
11047         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11048                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11049         case 0x0109:    /*Query File Stream Info*/
11050                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
11051                     &trunc);
11052                 break;
11053         case 0x010b:    /*Query File Compression Info*/
11054         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11055                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
11056                     &trunc);
11057                 break;
11058         case 0x0200:    /*Set File Unix Basic*/
11059                 /* XXX add this from the SNIA doc */
11060                 break;
11061         case 0x0201:    /*Set File Unix Link*/
11062                 /* XXX add this from the SNIA doc */
11063                 break;
11064         case 0x0202:    /*Set File Unix HardLink*/
11065                 /* XXX add this from the SNIA doc */
11066                 break;
11067         }
11068
11069         return offset;
11070 }
11071
11072
11073 static const true_false_string tfs_quota_flags_deny_disk = {
11074         "DENY DISK SPACE for users exceeding quota limit",
11075         "Do NOT deny disk space for users exceeding quota limit"
11076 };
11077 static const true_false_string tfs_quota_flags_log_limit = {
11078         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11079         "Do NOT log event when a user exceeds their quota limit"
11080 };
11081 static const true_false_string tfs_quota_flags_log_warning = {
11082         "LOG EVENT when a user exceeds their WARNING LEVEL",
11083         "Do NOT log event when a user exceeds their warning level"
11084 };
11085 static const true_false_string tfs_quota_flags_enabled = {
11086         "Quotas are ENABLED of this fs",
11087         "Quotas are NOT enabled on this fs"
11088 };
11089 static void
11090 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11091 {
11092         guint8 mask;
11093         proto_item *item = NULL;
11094         proto_tree *tree = NULL;
11095
11096         mask = tvb_get_guint8(tvb, offset);
11097
11098         if(parent_tree){
11099                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11100                         "Quota Flags: 0x%02x %s", mask,
11101                         mask?"Enabled":"Disabled");
11102                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11103         }
11104
11105         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11106                 tvb, offset, 1, mask);
11107         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11108                 tvb, offset, 1, mask);
11109         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11110                 tvb, offset, 1, mask);
11111
11112         if(mask && (!(mask&0x01))){
11113                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11114                         tvb, offset, 1, 0x01);
11115         } else {
11116                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11117                         tvb, offset, 1, mask);
11118         }
11119
11120 }
11121
11122 static int
11123 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11124 {
11125         /* first 24 bytes are unknown */
11126         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11127         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11128                     offset, 24, TRUE);
11129         COUNT_BYTES_TRANS_SUBR(24);
11130
11131         /* number of bytes for quota warning */
11132         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11133         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11134         COUNT_BYTES_TRANS_SUBR(8);
11135
11136         /* number of bytes for quota limit */
11137         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11138         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11139         COUNT_BYTES_TRANS_SUBR(8);
11140
11141         /* one byte of quota flags */
11142         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11143         dissect_quota_flags(tvb, tree, offset);
11144         COUNT_BYTES_TRANS_SUBR(1);
11145
11146         /* these 7 bytes are unknown */
11147         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11148         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11149                     offset, 7, TRUE);
11150         COUNT_BYTES_TRANS_SUBR(7);
11151
11152         return offset;
11153 }
11154
11155 static int
11156 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11157     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11158 {
11159         proto_item *item = NULL;
11160         proto_tree *tree = NULL;
11161         smb_info_t *si;
11162
11163         si = (smb_info_t *)pinfo->private_data;
11164
11165         if(parent_tree){
11166                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11167                                 "%s Data",
11168                                 val_to_str(subcmd, trans2_cmd_vals,
11169                                                 "Unknown (0x%02x)"));
11170                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11171         }
11172
11173         switch(subcmd){
11174         case 0x00:      /*TRANS2_OPEN2*/
11175                 /* XXX dont know how to decode FEAList */
11176                 break;
11177         case 0x01:      /*TRANS2_FIND_FIRST2*/
11178                 /* XXX dont know how to decode FEAList */
11179                 break;
11180         case 0x02:      /*TRANS2_FIND_NEXT2*/
11181                 /* XXX dont know how to decode FEAList */
11182                 break;
11183         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11184                 /* no data field in this request */
11185                 break;
11186         case 0x04:      /* TRANS2_SET_QUOTA */
11187                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11188                 break;
11189         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11190                 /* no data field in this request */
11191                 /*
11192                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11193                  * Extensions Version 3.0, Document Version 1.11,
11194                  * July 19, 1990" says there may be "Additional
11195                  * FileInfoLevel dependent information" here.
11196                  *
11197                  * Was that just a cut-and-pasteo?
11198                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11199                  * here.
11200                  */
11201                 break;
11202         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11203                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11204                 break;
11205         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11206                 /* no data field in this request */
11207                 /*
11208                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11209                  * Extensions Version 3.0, Document Version 1.11,
11210                  * July 19, 1990" says there may be "Additional
11211                  * FileInfoLevel dependent information" here.
11212                  *
11213                  * Was that just a cut-and-pasteo?
11214                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11215                  * here.
11216                  */
11217                 break;
11218         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11219                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11220                 break;
11221         case 0x09:      /*TRANS2_FSCTL*/
11222                 /*XXX dont know how to decode this yet */
11223
11224                 /*
11225                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11226                  * Extensions Version 3.0, Document Version 1.11,
11227                  * July 19, 1990" says this this contains a
11228                  * "File system specific data block".  (That means we
11229                  * may not be able to dissect it in any case.)
11230                  */
11231                 break;
11232         case 0x0a:      /*TRANS2_IOCTL2*/
11233                 /*XXX dont know how to decode this yet */
11234
11235                 /*
11236                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11237                  * Extensions Version 3.0, Document Version 1.11,
11238                  * July 19, 1990" says this this contains a
11239                  * "Device/function specific data block".  (That
11240                  * means we may not be able to dissect it in any case.)
11241                  */
11242                 break;
11243         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11244                 /*XXX dont know how to decode this yet */
11245
11246                 /*
11247                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11248                  * Extensions Version 3.0, Document Version 1.11,
11249                  * July 19, 1990" says this this contains "additional
11250                  * level dependent match data".
11251                  */
11252                 break;
11253         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11254                 /*XXX dont know how to decode this yet */
11255
11256                 /*
11257                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11258                  * Extensions Version 3.0, Document Version 1.11,
11259                  * July 19, 1990" says this this contains "additional
11260                  * level dependent monitor information".
11261                  */
11262                 break;
11263         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11264                 /* XXX optional FEAList, unknown what FEAList looks like*/
11265                 break;
11266         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11267                 /*XXX dont know how to decode this yet */
11268                 break;
11269         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11270                 /* no data field in this request */
11271                 break;
11272         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11273                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11274                 break;
11275         }
11276
11277         /* ooops there were data we didnt know how to process */
11278         if(dc != 0){
11279                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11280                 offset += dc;
11281         }
11282
11283         return offset;
11284 }
11285
11286
11287 static void
11288 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11289     proto_tree *tree)
11290 {
11291         int i;
11292         int offset;
11293         guint length;
11294
11295         /*
11296          * Show the setup words.
11297          */
11298         if (s_tvb != NULL) {
11299                 length = tvb_reported_length(s_tvb);
11300                 for (i = 0, offset = 0; length >= 2;
11301                     i++, offset += 2, length -= 2) {
11302                         /*
11303                          * XXX - add a setup word filterable field?
11304                          */
11305                         proto_tree_add_text(tree, s_tvb, offset, 2,
11306                             "Setup Word %d: 0x%04x", i,
11307                             tvb_get_letohs(s_tvb, offset));
11308                 }
11309         }
11310
11311         /*
11312          * Show the parameters, if any.
11313          */
11314         if (p_tvb != NULL) {
11315                 length = tvb_reported_length(p_tvb);
11316                 if (length != 0) {
11317                         proto_tree_add_text(tree, p_tvb, 0, length,
11318                             "Parameters: %s",
11319                             tvb_bytes_to_str(p_tvb, 0, length));
11320                 }
11321         }
11322
11323         /*
11324          * Show the data, if any.
11325          */
11326         if (d_tvb != NULL) {
11327                 length = tvb_reported_length(d_tvb);
11328                 if (length != 0) {
11329                         proto_tree_add_text(tree, d_tvb, 0, length,
11330                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11331                 }
11332         }
11333 }
11334
11335 /* This routine handles the following 4 calls
11336    Transaction  0x25
11337    Transaction Secondary 0x26
11338    Transaction2 0x32
11339    Transaction2 Secondary 0x33
11340 */
11341 static int
11342 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11343 {
11344         guint8 wc, sc=0;
11345         int so=offset;
11346         int sl=0;
11347         int spo=offset;
11348         int spc=0;
11349         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11350         int subcmd = -1;
11351         guint32 to;
11352         int an_len;
11353         const char *an = NULL;
11354         smb_info_t *si;
11355         smb_transact2_info_t *t2i;
11356         smb_transact_info_t *tri;
11357         guint16 bc;
11358         int padcnt;
11359         gboolean dissected_trans;
11360
11361         si = (smb_info_t *)pinfo->private_data;
11362
11363         WORD_COUNT;
11364
11365         if(wc==8){
11366                 /*secondary client request*/
11367
11368                 /* total param count, only a 16bit integer here*/
11369                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11370                 offset += 2;
11371
11372                 /* total data count , only 16bit integer here*/
11373                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11374                 offset += 2;
11375
11376                 /* param count */
11377                 pc = tvb_get_letohs(tvb, offset);
11378                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11379                 offset += 2;
11380
11381                 /* param offset */
11382                 po = tvb_get_letohs(tvb, offset);
11383                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11384                 offset += 2;
11385
11386                 /* param disp */
11387                 pd = tvb_get_letohs(tvb, offset);
11388                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11389                 offset += 2;
11390
11391                 /* data count */
11392                 dc = tvb_get_letohs(tvb, offset);
11393                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11394                 offset += 2;
11395
11396                 /* data offset */
11397                 od = tvb_get_letohs(tvb, offset);
11398                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11399                 offset += 2;
11400
11401                 /* data disp */
11402                 dd = tvb_get_letohs(tvb, offset);
11403                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11404                 offset += 2;
11405
11406                 if(si->cmd==SMB_COM_TRANSACTION2){
11407                         guint16 fid;
11408
11409                         /* fid */
11410                         fid = tvb_get_letohs(tvb, offset);
11411                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11412
11413                         offset += 2;
11414                 }
11415
11416                 /* There are no setup words. */
11417                 so = offset;
11418                 sc = 0;
11419                 sl = 0;
11420         } else {
11421                 /* it is not a secondary request */
11422
11423                 /* total param count , only a 16 bit integer here*/
11424                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11425                 offset += 2;
11426
11427                 /* total data count , only 16bit integer here*/
11428                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11429                 offset += 2;
11430
11431                 /* max param count , only 16bit integer here*/
11432                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11433                 offset += 2;
11434
11435                 /* max data count, only 16bit integer here*/
11436                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11437                 offset += 2;
11438
11439                 /* max setup count, only 16bit integer here*/
11440                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11441                 offset += 1;
11442
11443                 /* reserved byte */
11444                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11445                 offset += 1;
11446
11447                 /* transaction flags */
11448                 tf = dissect_transaction_flags(tvb, tree, offset);
11449                 offset += 2;
11450
11451                 /* timeout */
11452                 to = tvb_get_letohl(tvb, offset);
11453                 if (to == 0)
11454                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11455                 else if (to == 0xffffffff)
11456                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11457                 else
11458                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11459                 offset += 4;
11460
11461                 /* 2 reserved bytes */
11462                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11463                 offset += 2;
11464
11465                 /* param count */
11466                 pc = tvb_get_letohs(tvb, offset);
11467                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11468                 offset += 2;
11469
11470                 /* param offset */
11471                 po = tvb_get_letohs(tvb, offset);
11472                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11473                 offset += 2;
11474
11475                 /* param displacement is zero here */
11476                 pd = 0;
11477
11478                 /* data count */
11479                 dc = tvb_get_letohs(tvb, offset);
11480                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11481                 offset += 2;
11482
11483                 /* data offset */
11484                 od = tvb_get_letohs(tvb, offset);
11485                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11486                 offset += 2;
11487
11488                 /* data displacement is zero here */
11489                 dd = 0;
11490
11491                 /* setup count */
11492                 sc = tvb_get_guint8(tvb, offset);
11493                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11494                 offset += 1;
11495
11496                 /* reserved byte */
11497                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11498                 offset += 1;
11499
11500                 /* this is where the setup bytes, if any start */
11501                 so = offset;
11502                 sl = sc*2;
11503
11504                 /* if there were any setup bytes, decode them */
11505                 if(sc){
11506                         switch(si->cmd){
11507
11508                         case SMB_COM_TRANSACTION2:
11509                                 /* TRANSACTION2 only has one setup word and
11510                                    that is the subcommand code.
11511
11512                                    XXX - except for TRANS2_FSCTL
11513                                    and TRANS2_IOCTL. */
11514                                 subcmd = tvb_get_letohs(tvb, offset);
11515                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11516                                     tvb, offset, 2, subcmd);
11517                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11518                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11519                                             val_to_str(subcmd, trans2_cmd_vals,
11520                                                 "Unknown (0x%02x)"));
11521                                 }
11522                                 if (!si->unidir) {
11523                                         if(!pinfo->fd->flags.visited){
11524                                                 /*
11525                                                  * Allocate a new
11526                                                  * smb_transact2_info_t
11527                                                  * structure.
11528                                                  */
11529                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11530                                                 t2i->subcmd = subcmd;
11531                                                 t2i->info_level = -1;
11532                                                 t2i->resume_keys = FALSE;
11533                                                 si->sip->extra_info = t2i;
11534                                         }
11535                                 }
11536
11537                                 /*
11538                                  * XXX - process TRANS2_FSCTL and
11539                                  * TRANS2_IOCTL setup words here.
11540                                  */
11541                                 break;
11542
11543                         case SMB_COM_TRANSACTION:
11544                                 /* TRANSACTION setup words processed below */
11545                                 break;
11546                         }
11547
11548                         offset += sl;
11549                 }
11550         }
11551
11552         BYTE_COUNT;
11553
11554         if(wc!=8){
11555                 /* primary request */
11556                 /* name is NULL if transaction2 */
11557                 if(si->cmd == SMB_COM_TRANSACTION){
11558                         /* Transaction Name */
11559                         an = get_unicode_or_ascii_string(tvb, &offset,
11560                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11561                         if (an == NULL)
11562                                 goto endofcommand;
11563                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11564                                 offset, an_len, an);
11565                         COUNT_BYTES(an_len);
11566                 }
11567         }
11568
11569         /*
11570          * The pipe or mailslot arguments for Transaction start with
11571          * the first setup word (or where the first setup word would
11572          * be if there were any setup words), and run to the current
11573          * offset (which could mean that there aren't any).
11574          */
11575         spo = so;
11576         spc = offset - spo;
11577
11578         /* parameters */
11579         if(po>offset){
11580                 /* We have some initial padding bytes.
11581                 */
11582                 padcnt = po-offset;
11583                 if (padcnt > bc)
11584                         padcnt = bc;
11585                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11586                 COUNT_BYTES(padcnt);
11587         }
11588         if(pc){
11589                 CHECK_BYTE_COUNT(pc);
11590                 switch(si->cmd) {
11591
11592                 case SMB_COM_TRANSACTION2:
11593                         /* TRANSACTION2 parameters*/
11594                         offset = dissect_transaction2_request_parameters(tvb,
11595                             pinfo, tree, offset, subcmd, pc);
11596                         bc -= pc;
11597                         break;
11598
11599                 case SMB_COM_TRANSACTION:
11600                         /* TRANSACTION parameters processed below */
11601                         COUNT_BYTES(pc);
11602                         break;
11603                 }
11604         }
11605
11606         /* data */
11607         if(od>offset){
11608                 /* We have some initial padding bytes.
11609                 */
11610                 padcnt = od-offset;
11611                 if (padcnt > bc)
11612                         padcnt = bc;
11613                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11614                 COUNT_BYTES(padcnt);
11615         }
11616         if(dc){
11617                 CHECK_BYTE_COUNT(dc);
11618                 switch(si->cmd){
11619
11620                 case SMB_COM_TRANSACTION2:
11621                         /* TRANSACTION2 data*/
11622                         offset = dissect_transaction2_request_data(tvb, pinfo,
11623                             tree, offset, subcmd, dc);
11624                         bc -= dc;
11625                         break;
11626
11627                 case SMB_COM_TRANSACTION:
11628                         /* TRANSACTION data processed below */
11629                         COUNT_BYTES(dc);
11630                         break;
11631                 }
11632         }
11633
11634         /*TRANSACTION request parameters */
11635         if(si->cmd==SMB_COM_TRANSACTION){
11636                 /*XXX replace this block with a function and use that one
11637                      for both requests/responses*/
11638                 if(dd==0){
11639                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11640                         tvbuff_t *sp_tvb, *pd_tvb;
11641
11642                         if(pc>0){
11643                                 if(pc>tvb_length_remaining(tvb, po)){
11644                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11645                                 } else {
11646                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11647                                 }
11648                         } else {
11649                                 p_tvb = NULL;
11650                         }
11651                         if(dc>0){
11652                                 if(dc>tvb_length_remaining(tvb, od)){
11653                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11654                                 } else {
11655                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11656                                 }
11657                         } else {
11658                                 d_tvb = NULL;
11659                         }
11660                         if(sl){
11661                                 if(sl>tvb_length_remaining(tvb, so)){
11662                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11663                                 } else {
11664                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11665                                 }
11666                         } else {
11667                                 s_tvb = NULL;
11668                         }
11669
11670                         if (!si->unidir) {
11671                                 if(!pinfo->fd->flags.visited){
11672                                         /*
11673                                          * Allocate a new smb_transact_info_t
11674                                          * structure.
11675                                          */
11676                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11677                                         tri->subcmd = -1;
11678                                         tri->trans_subcmd = -1;
11679                                         tri->function = -1;
11680                                         tri->fid = -1;
11681                                         tri->lanman_cmd = 0;
11682                                         tri->param_descrip = NULL;
11683                                         tri->data_descrip = NULL;
11684                                         tri->aux_data_descrip = NULL;
11685                                         tri->info_level = -1;
11686                                         si->sip->extra_info = tri;
11687                                 } else {
11688                                         /*
11689                                          * We already filled the structure
11690                                          * in; don't bother doing so again.
11691                                          */
11692                                         tri = NULL;
11693                                 }
11694                         } else {
11695                                 /*
11696                                  * This is a unidirectional message, for
11697                                  * which there will be no reply; don't
11698                                  * bother allocating an "smb_transact_info_t"
11699                                  * structure for it.
11700                                  */
11701                                 tri = NULL;
11702                         }
11703                         dissected_trans = FALSE;
11704                         if(strncmp("\\PIPE\\", an, 6) == 0){
11705                                 if (tri != NULL)
11706                                         tri->subcmd=TRANSACTION_PIPE;
11707
11708                                 /*
11709                                  * A tvbuff containing the setup words and
11710                                  * the pipe path.
11711                                  */
11712                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11713
11714                                 /*
11715                                  * A tvbuff containing the parameters and the
11716                                  * data.
11717                                  */
11718                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11719
11720                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11721                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11722                                     top_tree);
11723
11724                                 /* In case we did not see the TreeConnect call,
11725                                    store this TID here as well as a IPC TID 
11726                                    so we know that future Read/Writes to this 
11727                                    TID is (probably) DCERPC.
11728                                 */
11729                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
11730                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
11731                                 }
11732                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
11733                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11734                                 if (tri != NULL)
11735                                         tri->subcmd=TRANSACTION_MAILSLOT;
11736
11737                                 /*
11738                                  * A tvbuff containing the setup words and
11739                                  * the mailslot path.
11740                                  */
11741                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11742                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11743                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11744                         }
11745                         if (!dissected_trans)
11746                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11747                 } else {
11748                         if(check_col(pinfo->cinfo, COL_INFO)){
11749                                 col_append_str(pinfo->cinfo, COL_INFO,
11750                                         "[transact continuation]");
11751                         }
11752                 }
11753         }
11754
11755         END_OF_SMB
11756
11757         return offset;
11758 }
11759
11760
11761
11762 static int
11763 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11764     int offset, guint16 *bcp, gboolean *trunc)
11765 {
11766         int fn_len;
11767         const char *fn;
11768         int old_offset = offset;
11769         proto_item *item = NULL;
11770         proto_tree *tree = NULL;
11771         smb_info_t *si;
11772         smb_transact2_info_t *t2i;
11773         gboolean resume_keys = FALSE;
11774
11775         si = (smb_info_t *)pinfo->private_data;
11776         if (si->sip != NULL) {
11777                 t2i = si->sip->extra_info;
11778                 if (t2i != NULL)
11779                         resume_keys = t2i->resume_keys;
11780         }
11781
11782         if(parent_tree){
11783                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11784                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11785                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11786         }
11787
11788         if (resume_keys) {
11789                 /* resume key */
11790                 CHECK_BYTE_COUNT_SUBR(4);
11791                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11792                 COUNT_BYTES_SUBR(4);
11793         }
11794
11795         /* create time */
11796         CHECK_BYTE_COUNT_SUBR(4);
11797         offset = dissect_smb_datetime(tvb, tree, offset,
11798                 hf_smb_create_time,
11799                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11800         *bcp -= 4;
11801
11802         /* access time */
11803         CHECK_BYTE_COUNT_SUBR(4);
11804         offset = dissect_smb_datetime(tvb, tree, offset,
11805                 hf_smb_access_time,
11806                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11807         *bcp -= 4;
11808
11809         /* last write time */
11810         CHECK_BYTE_COUNT_SUBR(4);
11811         offset = dissect_smb_datetime(tvb, tree, offset,
11812                 hf_smb_last_write_time,
11813                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11814         *bcp -= 4;
11815
11816         /* data size */
11817         CHECK_BYTE_COUNT_SUBR(4);
11818         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11819         COUNT_BYTES_SUBR(4);
11820
11821         /* allocation size */
11822         CHECK_BYTE_COUNT_SUBR(4);
11823         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11824         COUNT_BYTES_SUBR(4);
11825
11826         /* File Attributes */
11827         CHECK_BYTE_COUNT_SUBR(2);
11828         offset = dissect_file_attributes(tvb, tree, offset, 2);
11829         *bcp -= 2;
11830
11831         /* file name len */
11832         CHECK_BYTE_COUNT_SUBR(1);
11833         fn_len = tvb_get_guint8(tvb, offset);
11834         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11835         COUNT_BYTES_SUBR(1);
11836         if (si->unicode)
11837                 fn_len += 2;    /* include terminating '\0' */
11838         else
11839                 fn_len++;       /* include terminating '\0' */
11840
11841         /* file name */
11842         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11843         CHECK_STRING_SUBR(fn);
11844         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11845                 fn);
11846         COUNT_BYTES_SUBR(fn_len);
11847
11848         if (check_col(pinfo->cinfo, COL_INFO)) {
11849                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11850                 fn);
11851         }
11852
11853         proto_item_append_text(item, " File: %s", fn);
11854         proto_item_set_len(item, offset-old_offset);
11855
11856         *trunc = FALSE;
11857         return offset;
11858 }
11859
11860 static int
11861 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11862     int offset, guint16 *bcp, gboolean *trunc)
11863 {
11864         int fn_len;
11865         const char *fn;
11866         int old_offset = offset;
11867         proto_item *item = NULL;
11868         proto_tree *tree = NULL;
11869         smb_info_t *si;
11870         smb_transact2_info_t *t2i;
11871         gboolean resume_keys = FALSE;
11872
11873         si = (smb_info_t *)pinfo->private_data;
11874         if (si->sip != NULL) {
11875                 t2i = si->sip->extra_info;
11876                 if (t2i != NULL)
11877                         resume_keys = t2i->resume_keys;
11878         }
11879
11880         if(parent_tree){
11881                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11882                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11883                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11884         }
11885
11886         if (resume_keys) {
11887                 /* resume key */
11888                 CHECK_BYTE_COUNT_SUBR(4);
11889                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11890                 COUNT_BYTES_SUBR(4);
11891         }
11892
11893         /* create time */
11894         CHECK_BYTE_COUNT_SUBR(4);
11895         offset = dissect_smb_datetime(tvb, tree, offset,
11896                 hf_smb_create_time,
11897                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11898         *bcp -= 4;
11899
11900         /* access time */
11901         CHECK_BYTE_COUNT_SUBR(4);
11902         offset = dissect_smb_datetime(tvb, tree, offset,
11903                 hf_smb_access_time,
11904                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11905         *bcp -= 4;
11906
11907         /* last write time */
11908         CHECK_BYTE_COUNT_SUBR(4);
11909         offset = dissect_smb_datetime(tvb, tree, offset,
11910                 hf_smb_last_write_time,
11911                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11912         *bcp -= 4;
11913
11914         /* data size */
11915         CHECK_BYTE_COUNT_SUBR(4);
11916         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11917         COUNT_BYTES_SUBR(4);
11918
11919         /* allocation size */
11920         CHECK_BYTE_COUNT_SUBR(4);
11921         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11922         COUNT_BYTES_SUBR(4);
11923
11924         /* File Attributes */
11925         CHECK_BYTE_COUNT_SUBR(2);
11926         offset = dissect_file_attributes(tvb, tree, offset, 2);
11927         *bcp -= 2;
11928
11929         /* ea size */
11930         CHECK_BYTE_COUNT_SUBR(4);
11931         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11932         COUNT_BYTES_SUBR(4);
11933
11934         /* file name len */
11935         CHECK_BYTE_COUNT_SUBR(1);
11936         fn_len = tvb_get_guint8(tvb, offset);
11937         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11938         COUNT_BYTES_SUBR(1);
11939         if (si->unicode)
11940                 fn_len += 2;    /* include terminating '\0' */
11941         else
11942                 fn_len++;       /* include terminating '\0' */
11943
11944         /* file name */
11945         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11946         CHECK_STRING_SUBR(fn);
11947         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11948                 fn);
11949         COUNT_BYTES_SUBR(fn_len);
11950
11951         if (check_col(pinfo->cinfo, COL_INFO)) {
11952                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11953                 fn);
11954         }
11955
11956         proto_item_append_text(item, " File: %s", fn);
11957         proto_item_set_len(item, offset-old_offset);
11958
11959         *trunc = FALSE;
11960         return offset;
11961 }
11962
11963 static int
11964 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11965     int offset, guint16 *bcp, gboolean *trunc)
11966 {
11967         int fn_len;
11968         const char *fn;
11969         int old_offset = offset;
11970         proto_item *item = NULL;
11971         proto_tree *tree = NULL;
11972         smb_info_t *si;
11973         guint32 neo;
11974         int padcnt;
11975
11976         si = (smb_info_t *)pinfo->private_data;
11977
11978         if(parent_tree){
11979                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11980                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11981                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11982         }
11983
11984         /*
11985          * We assume that the presence of a next entry offset implies the
11986          * absence of a resume key, as appears to be the case for 4.3.4.6.
11987          */
11988
11989         /* next entry offset */
11990         CHECK_BYTE_COUNT_SUBR(4);
11991         neo = tvb_get_letohl(tvb, offset);
11992         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11993         COUNT_BYTES_SUBR(4);
11994
11995         /* file index */
11996         CHECK_BYTE_COUNT_SUBR(4);
11997         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11998         COUNT_BYTES_SUBR(4);
11999
12000         /* create time */
12001         CHECK_BYTE_COUNT_SUBR(8);
12002         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12003         *bcp -= 8;
12004
12005         /* access time */
12006         CHECK_BYTE_COUNT_SUBR(8);
12007         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12008         *bcp -= 8;
12009
12010         /* last write time */
12011         CHECK_BYTE_COUNT_SUBR(8);
12012         offset = dissect_smb_64bit_time(tvb, tree, offset,
12013                 hf_smb_last_write_time);
12014         *bcp -= 8;
12015
12016         /* last change time */
12017         CHECK_BYTE_COUNT_SUBR(8);
12018         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12019         *bcp -= 8;
12020
12021         /* end of file */
12022         CHECK_BYTE_COUNT_SUBR(8);
12023         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12024         COUNT_BYTES_SUBR(8);
12025
12026         /* allocation size */
12027         CHECK_BYTE_COUNT_SUBR(8);
12028         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12029         COUNT_BYTES_SUBR(8);
12030
12031         /* Extended File Attributes */
12032         CHECK_BYTE_COUNT_SUBR(4);
12033         offset = dissect_file_ext_attr(tvb, tree, offset);
12034         *bcp -= 4;
12035
12036         /* file name len */
12037         CHECK_BYTE_COUNT_SUBR(4);
12038         fn_len = tvb_get_letohl(tvb, offset);
12039         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12040         COUNT_BYTES_SUBR(4);
12041
12042         /* file name */
12043         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12044         CHECK_STRING_SUBR(fn);
12045         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12046                 fn);
12047         COUNT_BYTES_SUBR(fn_len);
12048
12049         if (check_col(pinfo->cinfo, COL_INFO)) {
12050                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12051                 fn);
12052         }
12053
12054         /* skip to next structure */
12055         if(neo){
12056                 padcnt = (old_offset + neo) - offset;
12057                 if (padcnt < 0) {
12058                         /*
12059                          * XXX - this is bogus; flag it?
12060                          */
12061                         padcnt = 0;
12062                 }
12063                 if (padcnt != 0) {
12064                         CHECK_BYTE_COUNT_SUBR(padcnt);
12065                         COUNT_BYTES_SUBR(padcnt);
12066                 }
12067         }
12068
12069         proto_item_append_text(item, " File: %s", fn);
12070         proto_item_set_len(item, offset-old_offset);
12071
12072         *trunc = FALSE;
12073         return offset;
12074 }
12075
12076 static int
12077 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12078     int offset, guint16 *bcp, gboolean *trunc)
12079 {
12080         int fn_len;
12081         const char *fn;
12082         int old_offset = offset;
12083         proto_item *item = NULL;
12084         proto_tree *tree = NULL;
12085         smb_info_t *si;
12086         guint32 neo;
12087         int padcnt;
12088
12089         si = (smb_info_t *)pinfo->private_data;
12090
12091         if(parent_tree){
12092                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12093                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12094                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12095         }
12096
12097         /*
12098          * We assume that the presence of a next entry offset implies the
12099          * absence of a resume key, as appears to be the case for 4.3.4.6.
12100          */
12101
12102         /* next entry offset */
12103         CHECK_BYTE_COUNT_SUBR(4);
12104         neo = tvb_get_letohl(tvb, offset);
12105         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12106         COUNT_BYTES_SUBR(4);
12107
12108         /* file index */
12109         CHECK_BYTE_COUNT_SUBR(4);
12110         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12111         COUNT_BYTES_SUBR(4);
12112
12113         /* create time */
12114         CHECK_BYTE_COUNT_SUBR(8);
12115         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12116         *bcp -= 8;
12117
12118         /* access time */
12119         CHECK_BYTE_COUNT_SUBR(8);
12120         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12121         *bcp -= 8;
12122
12123         /* last write time */
12124         CHECK_BYTE_COUNT_SUBR(8);
12125         offset = dissect_smb_64bit_time(tvb, tree, offset,
12126                 hf_smb_last_write_time);
12127         *bcp -= 8;
12128
12129         /* last change time */
12130         CHECK_BYTE_COUNT_SUBR(8);
12131         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12132         *bcp -= 8;
12133
12134         /* end of file */
12135         CHECK_BYTE_COUNT_SUBR(8);
12136         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12137         COUNT_BYTES_SUBR(8);
12138
12139         /* allocation size */
12140         CHECK_BYTE_COUNT_SUBR(8);
12141         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12142         COUNT_BYTES_SUBR(8);
12143
12144         /* Extended File Attributes */
12145         CHECK_BYTE_COUNT_SUBR(4);
12146         offset = dissect_file_ext_attr(tvb, tree, offset);
12147         *bcp -= 4;
12148
12149         /* file name len */
12150         CHECK_BYTE_COUNT_SUBR(4);
12151         fn_len = tvb_get_letohl(tvb, offset);
12152         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12153         COUNT_BYTES_SUBR(4);
12154
12155         /* ea size */
12156         CHECK_BYTE_COUNT_SUBR(4);
12157         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
12158         COUNT_BYTES_SUBR(4);
12159
12160         /* file name */
12161         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12162         CHECK_STRING_SUBR(fn);
12163         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12164                 fn);
12165         COUNT_BYTES_SUBR(fn_len);
12166
12167         if (check_col(pinfo->cinfo, COL_INFO)) {
12168                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12169                 fn);
12170         }
12171
12172         /* skip to next structure */
12173         if(neo){
12174                 padcnt = (old_offset + neo) - offset;
12175                 if (padcnt < 0) {
12176                         /*
12177                          * XXX - this is bogus; flag it?
12178                          */
12179                         padcnt = 0;
12180                 }
12181                 if (padcnt != 0) {
12182                         CHECK_BYTE_COUNT_SUBR(padcnt);
12183                         COUNT_BYTES_SUBR(padcnt);
12184                 }
12185         }
12186
12187         proto_item_append_text(item, " File: %s", fn);
12188         proto_item_set_len(item, offset-old_offset);
12189
12190         *trunc = FALSE;
12191         return offset;
12192 }
12193
12194 static int
12195 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12196     int offset, guint16 *bcp, gboolean *trunc)
12197 {
12198         int fn_len, sfn_len;
12199         const char *fn, *sfn;
12200         int old_offset = offset;
12201         proto_item *item = NULL;
12202         proto_tree *tree = NULL;
12203         smb_info_t *si;
12204         guint32 neo;
12205         int padcnt;
12206
12207         si = (smb_info_t *)pinfo->private_data;
12208
12209         if(parent_tree){
12210                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12211                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12212                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12213         }
12214
12215         /*
12216          * XXX - I have not seen any of these that contain a resume
12217          * key, even though some of the requests had the "return resume
12218          * key" flag set.
12219          */
12220
12221         /* next entry offset */
12222         CHECK_BYTE_COUNT_SUBR(4);
12223         neo = tvb_get_letohl(tvb, offset);
12224         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12225         COUNT_BYTES_SUBR(4);
12226
12227         /* file index */
12228         CHECK_BYTE_COUNT_SUBR(4);
12229         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12230         COUNT_BYTES_SUBR(4);
12231
12232         /* create time */
12233         CHECK_BYTE_COUNT_SUBR(8);
12234         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12235         *bcp -= 8;
12236
12237         /* access time */
12238         CHECK_BYTE_COUNT_SUBR(8);
12239         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12240         *bcp -= 8;
12241
12242         /* last write time */
12243         CHECK_BYTE_COUNT_SUBR(8);
12244         offset = dissect_smb_64bit_time(tvb, tree, offset,
12245                 hf_smb_last_write_time);
12246         *bcp -= 8;
12247
12248         /* last change time */
12249         CHECK_BYTE_COUNT_SUBR(8);
12250         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12251         *bcp -= 8;
12252
12253         /* end of file */
12254         CHECK_BYTE_COUNT_SUBR(8);
12255         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12256         COUNT_BYTES_SUBR(8);
12257
12258         /* allocation size */
12259         CHECK_BYTE_COUNT_SUBR(8);
12260         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12261         COUNT_BYTES_SUBR(8);
12262
12263         /* Extended File Attributes */
12264         CHECK_BYTE_COUNT_SUBR(4);
12265         offset = dissect_file_ext_attr(tvb, tree, offset);
12266         *bcp -= 4;
12267
12268         /* file name len */
12269         CHECK_BYTE_COUNT_SUBR(4);
12270         fn_len = tvb_get_letohl(tvb, offset);
12271         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12272         COUNT_BYTES_SUBR(4);
12273
12274         /* ea size */
12275         CHECK_BYTE_COUNT_SUBR(4);
12276         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
12277         COUNT_BYTES_SUBR(4);
12278
12279         /* short file name len */
12280         CHECK_BYTE_COUNT_SUBR(1);
12281         sfn_len = tvb_get_guint8(tvb, offset);
12282         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12283         COUNT_BYTES_SUBR(1);
12284
12285         /* reserved byte */
12286         CHECK_BYTE_COUNT_SUBR(1);
12287         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12288         COUNT_BYTES_SUBR(1);
12289
12290         /* short file name */
12291         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12292         CHECK_STRING_SUBR(sfn);
12293         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12294                 sfn);
12295         COUNT_BYTES_SUBR(24);
12296
12297         /* file name */
12298         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12299         CHECK_STRING_SUBR(fn);
12300         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12301                 fn);
12302         COUNT_BYTES_SUBR(fn_len);
12303
12304         if (check_col(pinfo->cinfo, COL_INFO)) {
12305                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12306                 fn);
12307         }
12308
12309         /* skip to next structure */
12310         if(neo){
12311                 padcnt = (old_offset + neo) - offset;
12312                 if (padcnt < 0) {
12313                         /*
12314                          * XXX - this is bogus; flag it?
12315                          */
12316                         padcnt = 0;
12317                 }
12318                 if (padcnt != 0) {
12319                         CHECK_BYTE_COUNT_SUBR(padcnt);
12320                         COUNT_BYTES_SUBR(padcnt);
12321                 }
12322         }
12323
12324         proto_item_append_text(item, " File: %s", fn);
12325         proto_item_set_len(item, offset-old_offset);
12326
12327         *trunc = FALSE;
12328         return offset;
12329 }
12330
12331 static int
12332 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12333     int offset, guint16 *bcp, gboolean *trunc)
12334 {
12335         int fn_len;
12336         const char *fn;
12337         int old_offset = offset;
12338         proto_item *item = NULL;
12339         proto_tree *tree = NULL;
12340         smb_info_t *si;
12341         guint32 neo;
12342         int padcnt;
12343
12344         si = (smb_info_t *)pinfo->private_data;
12345
12346         if(parent_tree){
12347                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12348                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12349                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12350         }
12351
12352         /*
12353          * We assume that the presence of a next entry offset implies the
12354          * absence of a resume key, as appears to be the case for 4.3.4.6.
12355          */
12356
12357         /* next entry offset */
12358         CHECK_BYTE_COUNT_SUBR(4);
12359         neo = tvb_get_letohl(tvb, offset);
12360         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12361         COUNT_BYTES_SUBR(4);
12362
12363         /* file index */
12364         CHECK_BYTE_COUNT_SUBR(4);
12365         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12366         COUNT_BYTES_SUBR(4);
12367
12368         /* file name len */
12369         CHECK_BYTE_COUNT_SUBR(4);
12370         fn_len = tvb_get_letohl(tvb, offset);
12371         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12372         COUNT_BYTES_SUBR(4);
12373
12374         /* file name */
12375         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12376         CHECK_STRING_SUBR(fn);
12377         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12378                 fn);
12379         COUNT_BYTES_SUBR(fn_len);
12380
12381         if (check_col(pinfo->cinfo, COL_INFO)) {
12382                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12383                 fn);
12384         }
12385
12386         /* skip to next structure */
12387         if(neo){
12388                 padcnt = (old_offset + neo) - offset;
12389                 if (padcnt < 0) {
12390                         /*
12391                          * XXX - this is bogus; flag it?
12392                          */
12393                         padcnt = 0;
12394                 }
12395                 if (padcnt != 0) {
12396                         CHECK_BYTE_COUNT_SUBR(padcnt);
12397                         COUNT_BYTES_SUBR(padcnt);
12398                 }
12399         }
12400
12401         proto_item_append_text(item, " File: %s", fn);
12402         proto_item_set_len(item, offset-old_offset);
12403
12404         *trunc = FALSE;
12405         return offset;
12406 }
12407
12408 static int
12409 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12410                 proto_tree *parent_tree _U_, int offset, guint16 *bcp,
12411                 gboolean *trunc)
12412 {
12413 /*XXX im lazy. i havnt implemented this */
12414         offset += *bcp;
12415         *bcp = 0;
12416         *trunc = FALSE;
12417         return offset;
12418 }
12419
12420 /*dissect the data block for TRANS2_FIND_FIRST2*/
12421 static int
12422 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12423     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12424 {
12425         smb_info_t *si;
12426
12427         if(!*bcp){
12428                 return offset;
12429         }
12430
12431         si = (smb_info_t *)pinfo->private_data;
12432         switch(si->info_level){
12433         case 1:         /*Info Standard*/
12434                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12435                     trunc);
12436                 break;
12437         case 2:         /*Info Query EA Size*/
12438                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12439                     trunc);
12440                 break;
12441         case 3:         /*Info Query EAs From List same as
12442                                 InfoQueryEASize*/
12443                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12444                     trunc);
12445                 break;
12446         case 0x0101:    /*Find File Directory Info*/
12447                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12448                     trunc);
12449                 break;
12450         case 0x0102:    /*Find File Full Directory Info*/
12451                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12452                     trunc);
12453                 break;
12454         case 0x0103:    /*Find File Names Info*/
12455                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12456                     trunc);
12457                 break;
12458         case 0x0104:    /*Find File Both Directory Info*/
12459                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12460                     trunc);
12461                 break;
12462         case 0x0202:    /*Find File UNIX*/
12463                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12464                     trunc);
12465                 break;
12466         default:        /* unknown info level */
12467                 *trunc = FALSE;
12468                 break;
12469         }
12470         return offset;
12471 }
12472
12473
12474 static int
12475 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12476 {
12477         guint32 mask;
12478         proto_item *item = NULL;
12479         proto_tree *tree = NULL;
12480
12481         mask = tvb_get_letohl(tvb, offset);
12482
12483         if(parent_tree){
12484                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12485                         "FS Attributes: 0x%08x", mask);
12486                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12487         }
12488
12489         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12490                 tvb, offset, 4, mask);
12491         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12492                 tvb, offset, 4, mask);
12493         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12494                 tvb, offset, 4, mask);
12495         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12496                 tvb, offset, 4, mask);
12497         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12498                 tvb, offset, 4, mask);
12499         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12500                 tvb, offset, 4, mask);
12501         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12502                 tvb, offset, 4, mask);
12503
12504         offset += 4;
12505         return offset;
12506 }
12507
12508
12509 static int
12510 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12511 {
12512         guint32 mask;
12513         proto_item *item = NULL;
12514         proto_tree *tree = NULL;
12515
12516         mask = tvb_get_letohl(tvb, offset);
12517
12518         if(parent_tree){
12519                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12520                         "Device Characteristics: 0x%08x", mask);
12521                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12522         }
12523
12524         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12525                 tvb, offset, 4, mask);
12526         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12527                 tvb, offset, 4, mask);
12528         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12529                 tvb, offset, 4, mask);
12530         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12531                 tvb, offset, 4, mask);
12532         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12533                 tvb, offset, 4, mask);
12534         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12535                 tvb, offset, 4, mask);
12536         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12537                 tvb, offset, 4, mask);
12538
12539         offset += 4;
12540         return offset;
12541 }
12542
12543 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12544
12545 static const true_false_string tfs_smb_mac_access_ctrl = {
12546   "Macintosh Access Control Supported",
12547   "Macintosh Access Control Not Supported"
12548 };
12549
12550 static const true_false_string tfs_smb_mac_getset_comments = {
12551   "Macintosh Get & Set Comments Supported",
12552   "Macintosh Get & Set Comments Not Supported"
12553 };
12554
12555 static const true_false_string tfs_smb_mac_desktopdb_calls = {
12556   "Macintosh Get & Set Desktop Database Info Supported",
12557   "Macintosh Get & Set Desktop Database Info Supported"
12558 };
12559
12560 static const true_false_string tfs_smb_mac_unique_ids = {
12561   "Macintosh Unique IDs Supported",
12562   "Macintosh Unique IDs Not Supported"
12563 };
12564
12565 static const true_false_string tfs_smb_mac_streams = {
12566   "Macintosh and Streams Extensions Not Supported",
12567   "Macintosh and Streams Extensions Supported"
12568 };
12569
12570 static int
12571 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12572     int offset, guint16 *bcp)
12573 {
12574         smb_info_t *si;
12575         int fn_len, vll, fnl;
12576         const char *fn;
12577         guint support = 0;
12578         proto_item *item = NULL;
12579         proto_tree *ti = NULL;
12580
12581         if(!*bcp){
12582                 return offset;
12583         }
12584
12585         si = (smb_info_t *)pinfo->private_data;
12586         switch(si->info_level){
12587         case 1:         /* SMB_INFO_ALLOCATION */
12588                 /* filesystem id */
12589                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12590                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12591                 COUNT_BYTES_TRANS_SUBR(4);
12592
12593                 /* sectors per unit */
12594                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12595                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12596                 COUNT_BYTES_TRANS_SUBR(4);
12597
12598                 /* units */
12599                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12600                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12601                 COUNT_BYTES_TRANS_SUBR(4);
12602
12603                 /* avail units */
12604                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12605                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12606                 COUNT_BYTES_TRANS_SUBR(4);
12607
12608                 /* bytes per sector, only 16bit integer here */
12609                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12610                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12611                 COUNT_BYTES_TRANS_SUBR(2);
12612
12613                 break;
12614         case 2:         /* SMB_INFO_VOLUME */
12615                 /* volume serial number */
12616                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12617                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12618                 COUNT_BYTES_TRANS_SUBR(4);
12619
12620                 /* volume label length, only one byte here */
12621                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12622                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12623                 COUNT_BYTES_TRANS_SUBR(1);
12624
12625                 /* label */
12626                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12627                 CHECK_STRING_TRANS_SUBR(fn);
12628                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12629                         fn);
12630                 COUNT_BYTES_TRANS_SUBR(fn_len);
12631
12632                 break;
12633         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12634         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12635                 /* volume label length */
12636                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12637                 vll = tvb_get_letohl(tvb, offset);
12638                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12639                 COUNT_BYTES_TRANS_SUBR(4);
12640
12641                 /* label */
12642                 fn_len = vll;
12643                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12644                 CHECK_STRING_TRANS_SUBR(fn);
12645                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12646                         fn);
12647                 COUNT_BYTES_TRANS_SUBR(fn_len);
12648
12649                 break;
12650         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12651         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12652                 /* create time */
12653                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12654                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12655                         hf_smb_create_time);
12656                 *bcp -= 8;
12657
12658                 /* volume serial number */
12659                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12660                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12661                 COUNT_BYTES_TRANS_SUBR(4);
12662
12663                 /* volume label length */
12664                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12665                 vll = tvb_get_letohl(tvb, offset);
12666                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12667                 COUNT_BYTES_TRANS_SUBR(4);
12668
12669                 /* 2 reserved bytes */
12670                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12671                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12672                 COUNT_BYTES_TRANS_SUBR(2);
12673
12674                 /* label */
12675                 fn_len = vll;
12676                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12677                 CHECK_STRING_TRANS_SUBR(fn);
12678                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12679                         fn);
12680                 COUNT_BYTES_TRANS_SUBR(fn_len);
12681
12682                 break;
12683         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12684         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12685                 /* allocation size */
12686                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12687                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12688                 COUNT_BYTES_TRANS_SUBR(8);
12689
12690                 /* free allocation units */
12691                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12692                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12693                 COUNT_BYTES_TRANS_SUBR(8);
12694
12695                 /* sectors per unit */
12696                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12697                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12698                 COUNT_BYTES_TRANS_SUBR(4);
12699
12700                 /* bytes per sector */
12701                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12702                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12703                 COUNT_BYTES_TRANS_SUBR(4);
12704
12705                 break;
12706         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12707         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12708                 /* device type */
12709                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12710                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12711                 COUNT_BYTES_TRANS_SUBR(4);
12712
12713                 /* device characteristics */
12714                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12715                 offset = dissect_device_characteristics(tvb, tree, offset);
12716                 *bcp -= 4;
12717
12718                 break;
12719         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12720         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12721                 /* FS attributes */
12722                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12723                 offset = dissect_fs_attributes(tvb, tree, offset);
12724                 *bcp -= 4;
12725
12726                 /* max name len */
12727                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12728                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12729                 COUNT_BYTES_TRANS_SUBR(4);
12730
12731                 /* fs name length */
12732                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12733                 fnl = tvb_get_letohl(tvb, offset);
12734                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12735                 COUNT_BYTES_TRANS_SUBR(4);
12736
12737                 /* label */
12738                 fn_len = fnl;
12739                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12740                 CHECK_STRING_TRANS_SUBR(fn);
12741                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12742                         fn);
12743                 COUNT_BYTES_TRANS_SUBR(fn_len);
12744
12745                 break;
12746         case 0x301:     /* MAC_QUERY_FS_INFO */
12747                 /* Create time */
12748                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12749                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12750                 *bcp -= 8;
12751                 /* Modify Time */
12752                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12753                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
12754                 *bcp -= 8;
12755                 /* Backup Time */
12756                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12757                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
12758                 *bcp -= 8;
12759                 /* Allocation blocks */
12760                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12761                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
12762                                     offset,
12763                                     4, TRUE);
12764                 COUNT_BYTES_TRANS_SUBR(4);
12765                 /* Allocation Block Size */
12766                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12767                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
12768                                     offset, 4, TRUE);
12769                 COUNT_BYTES_TRANS_SUBR(4);
12770                 /* Free Block Count */
12771                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12772                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
12773                                     offset, 4, TRUE);
12774                 COUNT_BYTES_TRANS_SUBR(4);
12775                 /* Finder Info ... */
12776                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
12777                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
12778                                             offset, 32,
12779                                             tvb_get_ptr(tvb, offset,32),
12780                                             "Finder Info: %s",
12781                                             tvb_format_text(tvb, offset, 32));
12782                 COUNT_BYTES_TRANS_SUBR(32);
12783                 /* Number Files */
12784                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12785                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
12786                                     offset, 4, TRUE);
12787                 COUNT_BYTES_TRANS_SUBR(4);
12788                 /* Number of Root Directories */
12789                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12790                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
12791                                     offset, 4, TRUE);
12792                 COUNT_BYTES_TRANS_SUBR(4);
12793                 /* Number of files */
12794                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12795                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
12796                                     offset, 4, TRUE);
12797                 COUNT_BYTES_TRANS_SUBR(4);
12798                 /* Dir Count */
12799                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12800                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
12801                                     offset, 4, TRUE);
12802                 COUNT_BYTES_TRANS_SUBR(4);
12803                 /* Mac Support Flags */
12804                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12805                 support = tvb_get_ntohl(tvb, offset);
12806                 item = proto_tree_add_text(tree, tvb, offset, 4,
12807                                            "Mac Support Flags: 0x%08x", support);
12808                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
12809                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
12810                                        tvb, offset, 4, support);
12811                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
12812                                        tvb, offset, 4, support);
12813                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
12814                                        tvb, offset, 4, support);
12815                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
12816                                        tvb, offset, 4, support);
12817                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
12818                                        tvb, offset, 4, support);
12819                 COUNT_BYTES_TRANS_SUBR(4);
12820                 break;
12821         case 1006:      /* QUERY_FS_QUOTA_INFO */
12822                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12823                 break;
12824         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12825                 /* allocation size */
12826                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12827                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12828                 COUNT_BYTES_TRANS_SUBR(8);
12829
12830                 /* caller free allocation units */
12831                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12832                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12833                 COUNT_BYTES_TRANS_SUBR(8);
12834
12835                 /* actual free allocation units */
12836                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12837                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12838                 COUNT_BYTES_TRANS_SUBR(8);
12839
12840                 /* sectors per unit */
12841                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12842                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12843                 COUNT_BYTES_TRANS_SUBR(4);
12844
12845                 /* bytes per sector */
12846                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12847                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12848                 COUNT_BYTES_TRANS_SUBR(4);
12849                 break;
12850         }
12851
12852         return offset;
12853 }
12854
12855 static int
12856 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12857     proto_tree *parent_tree)
12858 {
12859         proto_item *item = NULL;
12860         proto_tree *tree = NULL;
12861         smb_info_t *si;
12862         smb_transact2_info_t *t2i;
12863         int count;
12864         gboolean trunc;
12865         int offset = 0;
12866         guint16 dc;
12867
12868         dc = tvb_reported_length(tvb);
12869
12870         si = (smb_info_t *)pinfo->private_data;
12871         if (si->sip != NULL)
12872                 t2i = si->sip->extra_info;
12873         else
12874                 t2i = NULL;
12875
12876         if(parent_tree){
12877                 if (t2i != NULL && t2i->subcmd != -1) {
12878                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12879                                 "%s Data",
12880                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12881                                         "Unknown (0x%02x)"));
12882                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12883                 } else {
12884                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12885                                 "Unknown Transaction2 Data");
12886                 }
12887         }
12888
12889         if (t2i == NULL) {
12890                 offset += dc;
12891                 return offset;
12892         }
12893         switch(t2i->subcmd){
12894         case 0x00:      /*TRANS2_OPEN2*/
12895                 /* XXX not implemented yet. See SNIA doc */
12896                 break;
12897         case 0x01:      /*TRANS2_FIND_FIRST2*/
12898                 /* returned data */
12899                 count = si->info_count;
12900
12901                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12902                         col_append_fstr(pinfo->cinfo, COL_INFO,
12903                         ", Files:");
12904                 }
12905
12906                 while(count--){
12907                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12908                                 offset, &dc, &trunc);
12909                         if (trunc)
12910                                 break;
12911                 }
12912                 break;
12913         case 0x02:      /*TRANS2_FIND_NEXT2*/
12914                 /* returned data */
12915                 count = si->info_count;
12916
12917                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12918                         col_append_fstr(pinfo->cinfo, COL_INFO,
12919                         ", Files:");
12920                 }
12921
12922                 while(count--){
12923                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12924                                 offset, &dc, &trunc);
12925                         if (trunc)
12926                                 break;
12927                 }
12928                 break;
12929         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12930                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12931                 break;
12932         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12933                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12934                 break;
12935         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12936                 /* no data in this response */
12937                 break;
12938         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12939                 /* identical to QUERY_PATH_INFO */
12940                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12941                 break;
12942         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12943                 /* no data in this response */
12944                 break;
12945         case 0x09:      /*TRANS2_FSCTL*/
12946                 /* XXX dont know how to dissect this one (yet)*/
12947
12948                 /*
12949                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12950                  * Extensions Version 3.0, Document Version 1.11,
12951                  * July 19, 1990" says this this contains a
12952                  * "File system specific return data block".
12953                  * (That means we may not be able to dissect it in any
12954                  * case.)
12955                  */
12956                 break;
12957         case 0x0a:      /*TRANS2_IOCTL2*/
12958                 /* XXX dont know how to dissect this one (yet)*/
12959
12960                 /*
12961                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12962                  * Extensions Version 3.0, Document Version 1.11,
12963                  * July 19, 1990" says this this contains a
12964                  * "Device/function specific return data block".
12965                  * (That means we may not be able to dissect it in any
12966                  * case.)
12967                  */
12968                 break;
12969         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12970                 /* XXX dont know how to dissect this one (yet)*/
12971
12972                 /*
12973                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12974                  * Extensions Version 3.0, Document Version 1.11,
12975                  * July 19, 1990" says this this contains "the level
12976                  * dependent information about the changes which
12977                  * occurred".
12978                  */
12979                 break;
12980         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12981                 /* XXX dont know how to dissect this one (yet)*/
12982
12983                 /*
12984                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12985                  * Extensions Version 3.0, Document Version 1.11,
12986                  * July 19, 1990" says this this contains "the level
12987                  * dependent information about the changes which
12988                  * occurred".
12989                  */
12990                 break;
12991         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12992                 /* no data in this response */
12993                 break;
12994         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12995                 /* XXX dont know how to dissect this one (yet)*/
12996                 break;
12997         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12998                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12999                 break;
13000         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13001                 /* the SNIA spec appears to say the response has no data */
13002                 break;
13003         case -1:
13004                 /*
13005                  * We don't know what the matching request was; don't
13006                  * bother putting anything else into the tree for the data.
13007                  */
13008                 offset += dc;
13009                 dc = 0;
13010                 break;
13011         }
13012
13013         /* ooops there were data we didnt know how to process */
13014         if(dc != 0){
13015                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13016                 offset += dc;
13017         }
13018
13019         return offset;
13020 }
13021
13022
13023 static void
13024 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13025 {
13026         proto_item *item = NULL;
13027         proto_tree *tree = NULL;
13028         smb_info_t *si;
13029         smb_transact2_info_t *t2i;
13030         guint16 fid;
13031         int lno;
13032         int offset = 0;
13033         int pc;
13034
13035         pc = tvb_reported_length(tvb);
13036
13037         si = (smb_info_t *)pinfo->private_data;
13038         if (si->sip != NULL)
13039                 t2i = si->sip->extra_info;
13040         else
13041                 t2i = NULL;
13042
13043         if(parent_tree){
13044                 if (t2i != NULL && t2i->subcmd != -1) {
13045                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13046                                 "%s Parameters",
13047                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13048                                                 "Unknown (0x%02x)"));
13049                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13050                 } else {
13051                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13052                                 "Unknown Transaction2 Parameters");
13053                 }
13054         }
13055
13056         if (t2i == NULL) {
13057                 offset += pc;
13058                 return;
13059         }
13060         switch(t2i->subcmd){
13061         case 0x00:      /*TRANS2_OPEN2*/
13062                 /* fid */
13063                 fid = tvb_get_letohs(tvb, offset);
13064                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13065                 offset += 2;
13066
13067                 /*
13068                  * XXX - Microsoft Networks SMB File Sharing Protocol
13069                  * Extensions Version 3.0, Document Version 1.11,
13070                  * July 19, 1990 says that the file attributes, create
13071                  * time (which it says is the last modification time),
13072                  * data size, granted access, file type, and IPC state
13073                  * are returned only if bit 0 is set in the open flags,
13074                  * and that the EA length is returned only if bit 3
13075                  * is set in the open flags.  Does that mean that,
13076                  * at least in that SMB dialect, those fields are not
13077                  * present in the reply parameters if the bits in
13078                  * question aren't set?
13079                  */
13080
13081                 /* File Attributes */
13082                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13083
13084                 /* create time */
13085                 offset = dissect_smb_datetime(tvb, tree, offset,
13086                         hf_smb_create_time,
13087                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13088
13089                 /* data size */
13090                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13091                 offset += 4;
13092
13093                 /* granted access */
13094                 offset = dissect_access(tvb, tree, offset, "Granted");
13095
13096                 /* File Type */
13097                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13098                 offset += 2;
13099
13100                 /* IPC State */
13101                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13102
13103                 /* open_action */
13104                 offset = dissect_open_action(tvb, tree, offset);
13105
13106                 /* server unique file ID */
13107                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13108                 offset += 4;
13109
13110                 /* ea error offset, only a 16 bit integer here */
13111                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13112                 offset += 2;
13113
13114                 /* ea length */
13115                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
13116                 offset += 4;
13117
13118                 break;
13119         case 0x01:      /*TRANS2_FIND_FIRST2*/
13120                 /* Find First2 information level */
13121                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13122
13123                 /* sid */
13124                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13125                 offset += 2;
13126
13127                 /* search count */
13128                 si->info_count = tvb_get_letohs(tvb, offset);
13129                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13130                 offset += 2;
13131
13132                 /* end of search */
13133                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13134                 offset += 2;
13135
13136                 /* ea error offset, only a 16 bit integer here */
13137                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13138                 offset += 2;
13139
13140                 /* last name offset */
13141                 lno = tvb_get_letohs(tvb, offset);
13142                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13143                 offset += 2;
13144
13145                 break;
13146         case 0x02:      /*TRANS2_FIND_NEXT2*/
13147                 /* search count */
13148                 si->info_count = tvb_get_letohs(tvb, offset);
13149                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13150                 offset += 2;
13151
13152                 /* end of search */
13153                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13154                 offset += 2;
13155
13156                 /* ea_error_offset, only a 16 bit integer here*/
13157                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13158                 offset += 2;
13159
13160                 /* last name offset */
13161                 lno = tvb_get_letohs(tvb, offset);
13162                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13163                 offset += 2;
13164
13165                 break;
13166         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13167                 /* no parameter block here */
13168                 break;
13169         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13170                 /* ea_error_offset, only a 16 bit integer here*/
13171                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13172                 offset += 2;
13173
13174                 break;
13175         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13176                 /* ea_error_offset, only a 16 bit integer here*/
13177                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13178                 offset += 2;
13179
13180                 break;
13181         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13182                 /* ea_error_offset, only a 16 bit integer here*/
13183                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13184                 offset += 2;
13185
13186                 break;
13187         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13188                 /* ea_error_offset, only a 16 bit integer here*/
13189                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13190                 offset += 2;
13191
13192                 break;
13193         case 0x09:      /*TRANS2_FSCTL*/
13194                 /* XXX dont know how to dissect this one (yet)*/
13195
13196                 /*
13197                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13198                  * Extensions Version 3.0, Document Version 1.11,
13199                  * July 19, 1990" says this this contains a
13200                  * "File system specific return parameter block".
13201                  * (That means we may not be able to dissect it in any
13202                  * case.)
13203                  */
13204                 break;
13205         case 0x0a:      /*TRANS2_IOCTL2*/
13206                 /* XXX dont know how to dissect this one (yet)*/
13207
13208                 /*
13209                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13210                  * Extensions Version 3.0, Document Version 1.11,
13211                  * July 19, 1990" says this this contains a
13212                  * "Device/function specific return parameter block".
13213                  * (That means we may not be able to dissect it in any
13214                  * case.)
13215                  */
13216                 break;
13217         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13218                 /* Find Notify information level */
13219                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13220
13221                 /* Monitor handle */
13222                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13223                 offset += 2;
13224
13225                 /* Change count */
13226                 si->info_count = tvb_get_letohs(tvb, offset);
13227                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13228                 offset += 2;
13229
13230                 /* ea_error_offset, only a 16 bit integer here*/
13231                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13232                 offset += 2;
13233
13234                 break;
13235         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13236                 /* Find Notify information level */
13237                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13238
13239                 /* Change count */
13240                 si->info_count = tvb_get_letohs(tvb, offset);
13241                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13242                 offset += 2;
13243
13244                 /* ea_error_offset, only a 16 bit integer here*/
13245                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13246                 offset += 2;
13247
13248                 break;
13249         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13250                 /* ea error offset, only a 16 bit integer here */
13251                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13252                 offset += 2;
13253
13254                 break;
13255         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13256                 /* XXX dont know how to dissect this one (yet)*/
13257                 break;
13258         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13259                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13260                 break;
13261         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13262                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13263                 break;
13264         case -1:
13265                 /*
13266                  * We don't know what the matching request was; don't
13267                  * bother putting anything else into the tree for the data.
13268                  */
13269                 offset += pc;
13270                 break;
13271         }
13272
13273         /* ooops there were data we didnt know how to process */
13274         if(offset<pc){
13275                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13276                 offset += pc-offset;
13277         }
13278 }
13279
13280
13281 static int
13282 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13283 {
13284         guint8 sc, wc;
13285         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13286         smb_info_t *si;
13287         smb_transact2_info_t *t2i = NULL;
13288         guint16 bc;
13289         int padcnt;
13290         gboolean dissected_trans;
13291         fragment_data *r_fd = NULL;
13292         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13293         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13294         gboolean save_fragmented;
13295
13296         si = (smb_info_t *)pinfo->private_data;
13297
13298         switch(si->cmd){
13299         case SMB_COM_TRANSACTION2:
13300                 /* transaction2 */
13301                 if (si->sip != NULL) {
13302                         t2i = si->sip->extra_info;
13303                 } else
13304                         t2i = NULL;
13305                 if (t2i == NULL) {
13306                         /*
13307                          * We didn't see the matching request, so we don't
13308                          * know what type of transaction this is.
13309                          */
13310                         proto_tree_add_text(tree, tvb, 0, 0,
13311                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13312                         if (check_col(pinfo->cinfo, COL_INFO)) {
13313                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13314                         }
13315                 } else {
13316                         si->info_level = t2i->info_level;
13317                         if (t2i->subcmd == -1) {
13318                                 /*
13319                                  * We didn't manage to extract the subcommand
13320                                  * from the matching request (perhaps because
13321                                  * the frame was short), so we don't know what
13322                                  * type of transaction this is.
13323                                  */
13324                                 proto_tree_add_text(tree, tvb, 0, 0,
13325                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13326                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13327                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13328                                 }
13329                         } else {
13330                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13331                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13332                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13333                                                 val_to_str(t2i->subcmd,
13334                                                         trans2_cmd_vals,
13335                                                         "<unknown (0x%02x)>"));
13336                                 }
13337                         }
13338                 }
13339                 break;
13340         }
13341
13342         WORD_COUNT;
13343
13344         /* total param count, only a 16bit integer here */
13345         tp = tvb_get_letohs(tvb, offset);
13346         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
13347         offset += 2;
13348
13349         /* total data count, only a 16 bit integer here */
13350         td = tvb_get_letohs(tvb, offset);
13351         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
13352         offset += 2;
13353
13354         /* 2 reserved bytes */
13355         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13356         offset += 2;
13357
13358         /* param count */
13359         pc = tvb_get_letohs(tvb, offset);
13360         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13361         offset += 2;
13362
13363         /* param offset */
13364         po = tvb_get_letohs(tvb, offset);
13365         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13366         offset += 2;
13367
13368         /* param disp */
13369         pd = tvb_get_letohs(tvb, offset);
13370         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13371         offset += 2;
13372
13373         /* data count */
13374         dc = tvb_get_letohs(tvb, offset);
13375         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13376         offset += 2;
13377
13378         /* data offset */
13379         od = tvb_get_letohs(tvb, offset);
13380         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13381         offset += 2;
13382
13383         /* data disp */
13384         dd = tvb_get_letohs(tvb, offset);
13385         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13386         offset += 2;
13387
13388         /* setup count */
13389         sc = tvb_get_guint8(tvb, offset);
13390         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13391         offset += 1;
13392
13393         /* reserved byte */
13394         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13395         offset += 1;
13396
13397
13398         /* if there were any setup bytes, put them in a tvb for later */
13399         if(sc){
13400                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13401                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13402                 } else {
13403                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13404                 }
13405                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13406         } else {
13407                 s_tvb = NULL;
13408                 sp_tvb=NULL;
13409         }
13410         offset += 2*sc;
13411
13412
13413         BYTE_COUNT;
13414
13415
13416         /* reassembly of SMB Transaction data payload.
13417            In this section we do reassembly of both the data and parameters
13418            blocks of the SMB transaction command.
13419         */
13420         save_fragmented = pinfo->fragmented;
13421         /* do we need reassembly? */
13422         if( (td!=dc) || (tp!=pc) ){
13423                 /* oh yeah, either data or parameter section needs
13424                    reassembly
13425                 */
13426                 pinfo->fragmented = TRUE;
13427                 if(smb_trans_reassembly){
13428                         /* ...and we were told to do reassembly */
13429                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13430                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13431                                                              po, pc, pd, td+tp);
13432
13433                         }
13434                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13435                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13436                                                              od, dc, dd+tp, td+tp);
13437                         }
13438                 }
13439         }
13440
13441         /* if we got a reassembled fd structure from the reassembly routine we must
13442            create pd_tvb from it
13443         */
13444         if(r_fd){
13445                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13446                                              r_fd->datalen);
13447                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13448                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13449                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13450         }
13451
13452
13453         if(pd_tvb){
13454                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13455                 if(tp){
13456                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13457                 }
13458                 if(td){
13459                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13460                 }
13461         } else {
13462                 /* It was not reassembled. Do as best as we can.
13463                  * in this case we always try to dissect the stuff if
13464                  * data and param displacement is 0. i.e. for the first
13465                  * (and maybe only) packet.
13466                  */
13467                 if( (pd==0) && (dd==0) ){
13468                         int min;
13469                         int reported_min;
13470                         min = MIN(pc,tvb_length_remaining(tvb,po));
13471                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13472                         if(min && reported_min) {
13473                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13474                         }
13475                         min = MIN(dc,tvb_length_remaining(tvb,od));
13476                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13477                         if(min && reported_min) {
13478                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13479                         }
13480                         /*
13481                          * A tvbuff containing the parameters
13482                          * and the data.
13483                          * XXX - check pc and dc as well?
13484                          */
13485                         if (tvb_length_remaining(tvb, po)){
13486                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13487                         }
13488                 }
13489         }
13490
13491
13492
13493         /* parameters */
13494         if(po>offset){
13495                 /* We have some padding bytes.
13496                 */
13497                 padcnt = po-offset;
13498                 if (padcnt > bc)
13499                         padcnt = bc;
13500                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13501                 COUNT_BYTES(padcnt);
13502         }
13503         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
13504                 /* TRANSACTION2 parameters*/
13505                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
13506         }
13507         COUNT_BYTES(pc);
13508
13509
13510         /* data */
13511         if(od>offset){
13512                 /* We have some initial padding bytes.
13513                 */
13514                 padcnt = od-offset;
13515                 if (padcnt > bc)
13516                         padcnt = bc;
13517                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13518                 COUNT_BYTES(padcnt);
13519         }
13520         /*
13521          * If the data count is bigger than the count of bytes
13522          * remaining, clamp it so that the count of bytes remaining
13523          * doesn't go negative.
13524          */
13525         if (dc > bc)
13526                 dc = bc;
13527         COUNT_BYTES(dc);
13528
13529
13530
13531         /* from now on, everything is in separate tvbuffs so we dont count
13532            the bytes with COUNT_BYTES any more.
13533            neither do we reference offset any more (which by now points to the
13534            first byte AFTER this PDU */
13535
13536
13537         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
13538                 /* TRANSACTION2 parameters*/
13539                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
13540         }
13541
13542
13543         if(si->cmd==SMB_COM_TRANSACTION){
13544                 smb_transact_info_t *tri;
13545
13546                 dissected_trans = FALSE;
13547                 if (si->sip != NULL)
13548                         tri = si->sip->extra_info;
13549                 else
13550                         tri = NULL;
13551                 if (tri != NULL) {
13552                         switch(tri->subcmd){
13553
13554                         case TRANSACTION_PIPE:
13555                                 /* This function is safe to call for
13556                                    s_tvb==sp_tvb==NULL, i.e. if we don't
13557                                    know them at this point.
13558                                    It's also safe to call if "p_tvb"
13559                                    or "d_tvb" are null.
13560                                 */
13561                                 if( pd_tvb) {
13562                                         dissected_trans = dissect_pipe_smb(
13563                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
13564                                                 d_tvb, NULL, pinfo, top_tree);
13565                                 }
13566                                 break;
13567
13568                         case TRANSACTION_MAILSLOT:
13569                                 /* This one should be safe to call
13570                                    even if s_tvb and sp_tvb is NULL
13571                                 */
13572                                 if(d_tvb){
13573                                         dissected_trans = dissect_mailslot_smb(
13574                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
13575                                                 top_tree);
13576                                 }
13577                                 break;
13578                         }
13579                 }
13580                 if (!dissected_trans) {
13581                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
13582                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13583                 }
13584         }
13585
13586
13587         if( (p_tvb==0) && (d_tvb==0) ){
13588                 if(check_col(pinfo->cinfo, COL_INFO)){
13589                         col_append_str(pinfo->cinfo, COL_INFO,
13590                                        "[transact continuation]");
13591                 }
13592         }
13593
13594         pinfo->fragmented = save_fragmented;
13595         END_OF_SMB
13596
13597         return offset;
13598 }
13599
13600
13601 static int
13602 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13603 {
13604         guint8 wc;
13605         guint16 bc;
13606
13607         WORD_COUNT;
13608
13609         /* Monitor handle */
13610         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13611         offset += 2;
13612
13613         BYTE_COUNT;
13614
13615         END_OF_SMB
13616
13617         return offset;
13618 }
13619
13620 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13621    END Transaction/Transaction2 Primary and secondary requests
13622    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13623
13624
13625 static int
13626 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13627 {
13628         guint8 wc;
13629         guint16 bc;
13630
13631         WORD_COUNT;
13632
13633         if (wc != 0) {
13634                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13635                 offset += wc*2;
13636         }
13637
13638         BYTE_COUNT;
13639
13640         if (bc != 0) {
13641                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13642                 offset += bc;
13643                 bc = 0;
13644         }
13645
13646         END_OF_SMB
13647
13648         return offset;
13649 }
13650
13651 typedef struct _smb_function {
13652        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13653        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13654 } smb_function;
13655
13656 static smb_function smb_dissector[256] = {
13657   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13658   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13659   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13660   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13661   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13662   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13663   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13664   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13665   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13666   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13667   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13668   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13669   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13670   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13671   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13672   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13673
13674   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13675   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13676   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13677   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13678   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13679   /* 0x15 */  {dissect_unknown, dissect_unknown},
13680   /* 0x16 */  {dissect_unknown, dissect_unknown},
13681   /* 0x17 */  {dissect_unknown, dissect_unknown},
13682   /* 0x18 */  {dissect_unknown, dissect_unknown},
13683   /* 0x19 */  {dissect_unknown, dissect_unknown},
13684   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13685   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13686   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13687   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13688   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13689   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13690
13691   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13692   /* 0x21 */  {dissect_unknown, dissect_unknown},
13693   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13694   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13695   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13696   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13697   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13698   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13699   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13700   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13701   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13702   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13703   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13704   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13705   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13706   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13707
13708   /* 0x30 */  {dissect_unknown, dissect_unknown},
13709   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13710   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13711   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13712   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13713   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13714   /* 0x36 */  {dissect_unknown, dissect_unknown},
13715   /* 0x37 */  {dissect_unknown, dissect_unknown},
13716   /* 0x38 */  {dissect_unknown, dissect_unknown},
13717   /* 0x39 */  {dissect_unknown, dissect_unknown},
13718   /* 0x3a */  {dissect_unknown, dissect_unknown},
13719   /* 0x3b */  {dissect_unknown, dissect_unknown},
13720   /* 0x3c */  {dissect_unknown, dissect_unknown},
13721   /* 0x3d */  {dissect_unknown, dissect_unknown},
13722   /* 0x3e */  {dissect_unknown, dissect_unknown},
13723   /* 0x3f */  {dissect_unknown, dissect_unknown},
13724
13725   /* 0x40 */  {dissect_unknown, dissect_unknown},
13726   /* 0x41 */  {dissect_unknown, dissect_unknown},
13727   /* 0x42 */  {dissect_unknown, dissect_unknown},
13728   /* 0x43 */  {dissect_unknown, dissect_unknown},
13729   /* 0x44 */  {dissect_unknown, dissect_unknown},
13730   /* 0x45 */  {dissect_unknown, dissect_unknown},
13731   /* 0x46 */  {dissect_unknown, dissect_unknown},
13732   /* 0x47 */  {dissect_unknown, dissect_unknown},
13733   /* 0x48 */  {dissect_unknown, dissect_unknown},
13734   /* 0x49 */  {dissect_unknown, dissect_unknown},
13735   /* 0x4a */  {dissect_unknown, dissect_unknown},
13736   /* 0x4b */  {dissect_unknown, dissect_unknown},
13737   /* 0x4c */  {dissect_unknown, dissect_unknown},
13738   /* 0x4d */  {dissect_unknown, dissect_unknown},
13739   /* 0x4e */  {dissect_unknown, dissect_unknown},
13740   /* 0x4f */  {dissect_unknown, dissect_unknown},
13741
13742   /* 0x50 */  {dissect_unknown, dissect_unknown},
13743   /* 0x51 */  {dissect_unknown, dissect_unknown},
13744   /* 0x52 */  {dissect_unknown, dissect_unknown},
13745   /* 0x53 */  {dissect_unknown, dissect_unknown},
13746   /* 0x54 */  {dissect_unknown, dissect_unknown},
13747   /* 0x55 */  {dissect_unknown, dissect_unknown},
13748   /* 0x56 */  {dissect_unknown, dissect_unknown},
13749   /* 0x57 */  {dissect_unknown, dissect_unknown},
13750   /* 0x58 */  {dissect_unknown, dissect_unknown},
13751   /* 0x59 */  {dissect_unknown, dissect_unknown},
13752   /* 0x5a */  {dissect_unknown, dissect_unknown},
13753   /* 0x5b */  {dissect_unknown, dissect_unknown},
13754   /* 0x5c */  {dissect_unknown, dissect_unknown},
13755   /* 0x5d */  {dissect_unknown, dissect_unknown},
13756   /* 0x5e */  {dissect_unknown, dissect_unknown},
13757   /* 0x5f */  {dissect_unknown, dissect_unknown},
13758
13759   /* 0x60 */  {dissect_unknown, dissect_unknown},
13760   /* 0x61 */  {dissect_unknown, dissect_unknown},
13761   /* 0x62 */  {dissect_unknown, dissect_unknown},
13762   /* 0x63 */  {dissect_unknown, dissect_unknown},
13763   /* 0x64 */  {dissect_unknown, dissect_unknown},
13764   /* 0x65 */  {dissect_unknown, dissect_unknown},
13765   /* 0x66 */  {dissect_unknown, dissect_unknown},
13766   /* 0x67 */  {dissect_unknown, dissect_unknown},
13767   /* 0x68 */  {dissect_unknown, dissect_unknown},
13768   /* 0x69 */  {dissect_unknown, dissect_unknown},
13769   /* 0x6a */  {dissect_unknown, dissect_unknown},
13770   /* 0x6b */  {dissect_unknown, dissect_unknown},
13771   /* 0x6c */  {dissect_unknown, dissect_unknown},
13772   /* 0x6d */  {dissect_unknown, dissect_unknown},
13773   /* 0x6e */  {dissect_unknown, dissect_unknown},
13774   /* 0x6f */  {dissect_unknown, dissect_unknown},
13775
13776   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13777   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13778   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13779   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13780   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13781   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13782   /* 0x76 */  {dissect_unknown, dissect_unknown},
13783   /* 0x77 */  {dissect_unknown, dissect_unknown},
13784   /* 0x78 */  {dissect_unknown, dissect_unknown},
13785   /* 0x79 */  {dissect_unknown, dissect_unknown},
13786   /* 0x7a */  {dissect_unknown, dissect_unknown},
13787   /* 0x7b */  {dissect_unknown, dissect_unknown},
13788   /* 0x7c */  {dissect_unknown, dissect_unknown},
13789   /* 0x7d */  {dissect_unknown, dissect_unknown},
13790   /* 0x7e */  {dissect_unknown, dissect_unknown},
13791   /* 0x7f */  {dissect_unknown, dissect_unknown},
13792
13793   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13794   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13795   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13796   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13797   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13798   /* 0x85 */  {dissect_unknown, dissect_unknown},
13799   /* 0x86 */  {dissect_unknown, dissect_unknown},
13800   /* 0x87 */  {dissect_unknown, dissect_unknown},
13801   /* 0x88 */  {dissect_unknown, dissect_unknown},
13802   /* 0x89 */  {dissect_unknown, dissect_unknown},
13803   /* 0x8a */  {dissect_unknown, dissect_unknown},
13804   /* 0x8b */  {dissect_unknown, dissect_unknown},
13805   /* 0x8c */  {dissect_unknown, dissect_unknown},
13806   /* 0x8d */  {dissect_unknown, dissect_unknown},
13807   /* 0x8e */  {dissect_unknown, dissect_unknown},
13808   /* 0x8f */  {dissect_unknown, dissect_unknown},
13809
13810   /* 0x90 */  {dissect_unknown, dissect_unknown},
13811   /* 0x91 */  {dissect_unknown, dissect_unknown},
13812   /* 0x92 */  {dissect_unknown, dissect_unknown},
13813   /* 0x93 */  {dissect_unknown, dissect_unknown},
13814   /* 0x94 */  {dissect_unknown, dissect_unknown},
13815   /* 0x95 */  {dissect_unknown, dissect_unknown},
13816   /* 0x96 */  {dissect_unknown, dissect_unknown},
13817   /* 0x97 */  {dissect_unknown, dissect_unknown},
13818   /* 0x98 */  {dissect_unknown, dissect_unknown},
13819   /* 0x99 */  {dissect_unknown, dissect_unknown},
13820   /* 0x9a */  {dissect_unknown, dissect_unknown},
13821   /* 0x9b */  {dissect_unknown, dissect_unknown},
13822   /* 0x9c */  {dissect_unknown, dissect_unknown},
13823   /* 0x9d */  {dissect_unknown, dissect_unknown},
13824   /* 0x9e */  {dissect_unknown, dissect_unknown},
13825   /* 0x9f */  {dissect_unknown, dissect_unknown},
13826
13827   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13828   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13829   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13830   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13831   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13832   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13833   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13834   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13835   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13836   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13837   /* 0xaa */  {dissect_unknown, dissect_unknown},
13838   /* 0xab */  {dissect_unknown, dissect_unknown},
13839   /* 0xac */  {dissect_unknown, dissect_unknown},
13840   /* 0xad */  {dissect_unknown, dissect_unknown},
13841   /* 0xae */  {dissect_unknown, dissect_unknown},
13842   /* 0xaf */  {dissect_unknown, dissect_unknown},
13843
13844   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13845   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13846   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13847   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13848   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13849   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13850   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13851   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13852   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13853   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13854   /* 0xba */  {dissect_unknown, dissect_unknown},
13855   /* 0xbb */  {dissect_unknown, dissect_unknown},
13856   /* 0xbc */  {dissect_unknown, dissect_unknown},
13857   /* 0xbd */  {dissect_unknown, dissect_unknown},
13858   /* 0xbe */  {dissect_unknown, dissect_unknown},
13859   /* 0xbf */  {dissect_unknown, dissect_unknown},
13860
13861   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13862   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13863   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13864   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13865   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13866   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13867   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13868   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13869   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13870   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13871   /* 0xca */  {dissect_unknown, dissect_unknown},
13872   /* 0xcb */  {dissect_unknown, dissect_unknown},
13873   /* 0xcc */  {dissect_unknown, dissect_unknown},
13874   /* 0xcd */  {dissect_unknown, dissect_unknown},
13875   /* 0xce */  {dissect_unknown, dissect_unknown},
13876   /* 0xcf */  {dissect_unknown, dissect_unknown},
13877
13878   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13879   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13880   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13881   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13882   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13883   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13884   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13885   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13886   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13887   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13888   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13889   /* 0xdb */  {dissect_unknown, dissect_unknown},
13890   /* 0xdc */  {dissect_unknown, dissect_unknown},
13891   /* 0xdd */  {dissect_unknown, dissect_unknown},
13892   /* 0xde */  {dissect_unknown, dissect_unknown},
13893   /* 0xdf */  {dissect_unknown, dissect_unknown},
13894
13895   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13896   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13897   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13898   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13899   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13900   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13901   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13902   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13903   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13904   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13905   /* 0xea */  {dissect_unknown, dissect_unknown},
13906   /* 0xeb */  {dissect_unknown, dissect_unknown},
13907   /* 0xec */  {dissect_unknown, dissect_unknown},
13908   /* 0xed */  {dissect_unknown, dissect_unknown},
13909   /* 0xee */  {dissect_unknown, dissect_unknown},
13910   /* 0xef */  {dissect_unknown, dissect_unknown},
13911
13912   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13913   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13914   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13915   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13916   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13917   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13918   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13919   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13920   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13921   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13922   /* 0xfa */  {dissect_unknown, dissect_unknown},
13923   /* 0xfb */  {dissect_unknown, dissect_unknown},
13924   /* 0xfc */  {dissect_unknown, dissect_unknown},
13925   /* 0xfd */  {dissect_unknown, dissect_unknown},
13926   /* 0xfe */  {dissect_unknown, dissect_unknown},
13927   /* 0xff */  {dissect_unknown, dissect_unknown},
13928 };
13929
13930 static int
13931 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
13932 {
13933         smb_info_t *si;
13934
13935         si = pinfo->private_data;
13936         if(cmd!=0xff){
13937                 proto_item *cmd_item;
13938                 proto_tree *cmd_tree;
13939                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13940
13941                 if (check_col(pinfo->cinfo, COL_INFO)) {
13942                         if(first_pdu){
13943                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13944                                         "%s %s",
13945                                         decode_smb_name(cmd),
13946                                         (si->request)? "Request" : "Response");
13947                         } else {
13948                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13949                                         "; %s",
13950                                         decode_smb_name(cmd));
13951                         }
13952
13953                 }
13954
13955                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13956                         "%s %s (0x%02x)",
13957                         decode_smb_name(cmd),
13958                         (si->request)?"Request":"Response",
13959                         cmd);
13960
13961                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13962
13963                 dissector = (si->request)?
13964                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13965
13966                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13967                 proto_item_set_end(cmd_item, tvb, offset);
13968         }
13969         return offset;
13970 }
13971
13972
13973 /* NOTE: this value_string array will also be used to access data directly by
13974  * index instead of val_to_str() since
13975  * 1, the array will always span every value from 0x00 to 0xff and
13976  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13977  * This means that this value_string array MUST always
13978  * 1, contain all entries 0x00 to 0xff
13979  * 2, all entries must be in order.
13980  */
13981 const value_string smb_cmd_vals[] = {
13982   { 0x00, "Create Directory" },
13983   { 0x01, "Delete Directory" },
13984   { 0x02, "Open" },
13985   { 0x03, "Create" },
13986   { 0x04, "Close" },
13987   { 0x05, "Flush" },
13988   { 0x06, "Delete" },
13989   { 0x07, "Rename" },
13990   { 0x08, "Query Information" },
13991   { 0x09, "Set Information" },
13992   { 0x0A, "Read" },
13993   { 0x0B, "Write" },
13994   { 0x0C, "Lock Byte Range" },
13995   { 0x0D, "Unlock Byte Range" },
13996   { 0x0E, "Create Temp" },
13997   { 0x0F, "Create New" },
13998   { 0x10, "Check Directory" },
13999   { 0x11, "Process Exit" },
14000   { 0x12, "Seek" },
14001   { 0x13, "Lock And Read" },
14002   { 0x14, "Write And Unlock" },
14003   { 0x15, "unknown-0x15" },
14004   { 0x16, "unknown-0x16" },
14005   { 0x17, "unknown-0x17" },
14006   { 0x18, "unknown-0x18" },
14007   { 0x19, "unknown-0x19" },
14008   { 0x1A, "Read Raw" },
14009   { 0x1B, "Read MPX" },
14010   { 0x1C, "Read MPX Secondary" },
14011   { 0x1D, "Write Raw" },
14012   { 0x1E, "Write MPX" },
14013   { 0x1F, "Write MPX Secondary" },
14014   { 0x20, "Write Complete" },
14015   { 0x21, "unknown-0x21" },
14016   { 0x22, "Set Information2" },
14017   { 0x23, "Query Information2" },
14018   { 0x24, "Locking AndX" },
14019   { 0x25, "Transaction" },
14020   { 0x26, "Transaction Secondary" },
14021   { 0x27, "IOCTL" },
14022   { 0x28, "IOCTL Secondary" },
14023   { 0x29, "Copy" },
14024   { 0x2A, "Move" },
14025   { 0x2B, "Echo" },
14026   { 0x2C, "Write And Close" },
14027   { 0x2D, "Open AndX" },
14028   { 0x2E, "Read AndX" },
14029   { 0x2F, "Write AndX" },
14030   { 0x30, "unknown-0x30" },
14031   { 0x31, "Close And Tree Disconnect" },
14032   { 0x32, "Transaction2" },
14033   { 0x33, "Transaction2 Secondary" },
14034   { 0x34, "Find Close2" },
14035   { 0x35, "Find Notify Close" },
14036   { 0x36, "unknown-0x36" },
14037   { 0x37, "unknown-0x37" },
14038   { 0x38, "unknown-0x38" },
14039   { 0x39, "unknown-0x39" },
14040   { 0x3A, "unknown-0x3A" },
14041   { 0x3B, "unknown-0x3B" },
14042   { 0x3C, "unknown-0x3C" },
14043   { 0x3D, "unknown-0x3D" },
14044   { 0x3E, "unknown-0x3E" },
14045   { 0x3F, "unknown-0x3F" },
14046   { 0x40, "unknown-0x40" },
14047   { 0x41, "unknown-0x41" },
14048   { 0x42, "unknown-0x42" },
14049   { 0x43, "unknown-0x43" },
14050   { 0x44, "unknown-0x44" },
14051   { 0x45, "unknown-0x45" },
14052   { 0x46, "unknown-0x46" },
14053   { 0x47, "unknown-0x47" },
14054   { 0x48, "unknown-0x48" },
14055   { 0x49, "unknown-0x49" },
14056   { 0x4A, "unknown-0x4A" },
14057   { 0x4B, "unknown-0x4B" },
14058   { 0x4C, "unknown-0x4C" },
14059   { 0x4D, "unknown-0x4D" },
14060   { 0x4E, "unknown-0x4E" },
14061   { 0x4F, "unknown-0x4F" },
14062   { 0x50, "unknown-0x50" },
14063   { 0x51, "unknown-0x51" },
14064   { 0x52, "unknown-0x52" },
14065   { 0x53, "unknown-0x53" },
14066   { 0x54, "unknown-0x54" },
14067   { 0x55, "unknown-0x55" },
14068   { 0x56, "unknown-0x56" },
14069   { 0x57, "unknown-0x57" },
14070   { 0x58, "unknown-0x58" },
14071   { 0x59, "unknown-0x59" },
14072   { 0x5A, "unknown-0x5A" },
14073   { 0x5B, "unknown-0x5B" },
14074   { 0x5C, "unknown-0x5C" },
14075   { 0x5D, "unknown-0x5D" },
14076   { 0x5E, "unknown-0x5E" },
14077   { 0x5F, "unknown-0x5F" },
14078   { 0x60, "unknown-0x60" },
14079   { 0x61, "unknown-0x61" },
14080   { 0x62, "unknown-0x62" },
14081   { 0x63, "unknown-0x63" },
14082   { 0x64, "unknown-0x64" },
14083   { 0x65, "unknown-0x65" },
14084   { 0x66, "unknown-0x66" },
14085   { 0x67, "unknown-0x67" },
14086   { 0x68, "unknown-0x68" },
14087   { 0x69, "unknown-0x69" },
14088   { 0x6A, "unknown-0x6A" },
14089   { 0x6B, "unknown-0x6B" },
14090   { 0x6C, "unknown-0x6C" },
14091   { 0x6D, "unknown-0x6D" },
14092   { 0x6E, "unknown-0x6E" },
14093   { 0x6F, "unknown-0x6F" },
14094   { 0x70, "Tree Connect" },
14095   { 0x71, "Tree Disconnect" },
14096   { 0x72, "Negotiate Protocol" },
14097   { 0x73, "Session Setup AndX" },
14098   { 0x74, "Logoff AndX" },
14099   { 0x75, "Tree Connect AndX" },
14100   { 0x76, "unknown-0x76" },
14101   { 0x77, "unknown-0x77" },
14102   { 0x78, "unknown-0x78" },
14103   { 0x79, "unknown-0x79" },
14104   { 0x7A, "unknown-0x7A" },
14105   { 0x7B, "unknown-0x7B" },
14106   { 0x7C, "unknown-0x7C" },
14107   { 0x7D, "unknown-0x7D" },
14108   { 0x7E, "unknown-0x7E" },
14109   { 0x7F, "unknown-0x7F" },
14110   { 0x80, "Query Information Disk" },
14111   { 0x81, "Search" },
14112   { 0x82, "Find" },
14113   { 0x83, "Find Unique" },
14114   { 0x84, "Find Close" },
14115   { 0x85, "unknown-0x85" },
14116   { 0x86, "unknown-0x86" },
14117   { 0x87, "unknown-0x87" },
14118   { 0x88, "unknown-0x88" },
14119   { 0x89, "unknown-0x89" },
14120   { 0x8A, "unknown-0x8A" },
14121   { 0x8B, "unknown-0x8B" },
14122   { 0x8C, "unknown-0x8C" },
14123   { 0x8D, "unknown-0x8D" },
14124   { 0x8E, "unknown-0x8E" },
14125   { 0x8F, "unknown-0x8F" },
14126   { 0x90, "unknown-0x90" },
14127   { 0x91, "unknown-0x91" },
14128   { 0x92, "unknown-0x92" },
14129   { 0x93, "unknown-0x93" },
14130   { 0x94, "unknown-0x94" },
14131   { 0x95, "unknown-0x95" },
14132   { 0x96, "unknown-0x96" },
14133   { 0x97, "unknown-0x97" },
14134   { 0x98, "unknown-0x98" },
14135   { 0x99, "unknown-0x99" },
14136   { 0x9A, "unknown-0x9A" },
14137   { 0x9B, "unknown-0x9B" },
14138   { 0x9C, "unknown-0x9C" },
14139   { 0x9D, "unknown-0x9D" },
14140   { 0x9E, "unknown-0x9E" },
14141   { 0x9F, "unknown-0x9F" },
14142   { 0xA0, "NT Transact" },
14143   { 0xA1, "NT Transact Secondary" },
14144   { 0xA2, "NT Create AndX" },
14145   { 0xA3, "unknown-0xA3" },
14146   { 0xA4, "NT Cancel" },
14147   { 0xA5, "NT Rename" },
14148   { 0xA6, "unknown-0xA6" },
14149   { 0xA7, "unknown-0xA7" },
14150   { 0xA8, "unknown-0xA8" },
14151   { 0xA9, "unknown-0xA9" },
14152   { 0xAA, "unknown-0xAA" },
14153   { 0xAB, "unknown-0xAB" },
14154   { 0xAC, "unknown-0xAC" },
14155   { 0xAD, "unknown-0xAD" },
14156   { 0xAE, "unknown-0xAE" },
14157   { 0xAF, "unknown-0xAF" },
14158   { 0xB0, "unknown-0xB0" },
14159   { 0xB1, "unknown-0xB1" },
14160   { 0xB2, "unknown-0xB2" },
14161   { 0xB3, "unknown-0xB3" },
14162   { 0xB4, "unknown-0xB4" },
14163   { 0xB5, "unknown-0xB5" },
14164   { 0xB6, "unknown-0xB6" },
14165   { 0xB7, "unknown-0xB7" },
14166   { 0xB8, "unknown-0xB8" },
14167   { 0xB9, "unknown-0xB9" },
14168   { 0xBA, "unknown-0xBA" },
14169   { 0xBB, "unknown-0xBB" },
14170   { 0xBC, "unknown-0xBC" },
14171   { 0xBD, "unknown-0xBD" },
14172   { 0xBE, "unknown-0xBE" },
14173   { 0xBF, "unknown-0xBF" },
14174   { 0xC0, "Open Print File" },
14175   { 0xC1, "Write Print File" },
14176   { 0xC2, "Close Print File" },
14177   { 0xC3, "Get Print Queue" },
14178   { 0xC4, "unknown-0xC4" },
14179   { 0xC5, "unknown-0xC5" },
14180   { 0xC6, "unknown-0xC6" },
14181   { 0xC7, "unknown-0xC7" },
14182   { 0xC8, "unknown-0xC8" },
14183   { 0xC9, "unknown-0xC9" },
14184   { 0xCA, "unknown-0xCA" },
14185   { 0xCB, "unknown-0xCB" },
14186   { 0xCC, "unknown-0xCC" },
14187   { 0xCD, "unknown-0xCD" },
14188   { 0xCE, "unknown-0xCE" },
14189   { 0xCF, "unknown-0xCF" },
14190   { 0xD0, "Send Single Block Message" },
14191   { 0xD1, "Send Broadcast Message" },
14192   { 0xD2, "Forward User Name" },
14193   { 0xD3, "Cancel Forward" },
14194   { 0xD4, "Get Machine Name" },
14195   { 0xD5, "Send Start of Multi-block Message" },
14196   { 0xD6, "Send End of Multi-block Message" },
14197   { 0xD7, "Send Text of Multi-block Message" },
14198   { 0xD8, "SMBreadbulk" },
14199   { 0xD9, "SMBwritebulk" },
14200   { 0xDA, "SMBwritebulkdata" },
14201   { 0xDB, "unknown-0xDB" },
14202   { 0xDC, "unknown-0xDC" },
14203   { 0xDD, "unknown-0xDD" },
14204   { 0xDE, "unknown-0xDE" },
14205   { 0xDF, "unknown-0xDF" },
14206   { 0xE0, "unknown-0xE0" },
14207   { 0xE1, "unknown-0xE1" },
14208   { 0xE2, "unknown-0xE2" },
14209   { 0xE3, "unknown-0xE3" },
14210   { 0xE4, "unknown-0xE4" },
14211   { 0xE5, "unknown-0xE5" },
14212   { 0xE6, "unknown-0xE6" },
14213   { 0xE7, "unknown-0xE7" },
14214   { 0xE8, "unknown-0xE8" },
14215   { 0xE9, "unknown-0xE9" },
14216   { 0xEA, "unknown-0xEA" },
14217   { 0xEB, "unknown-0xEB" },
14218   { 0xEC, "unknown-0xEC" },
14219   { 0xED, "unknown-0xED" },
14220   { 0xEE, "unknown-0xEE" },
14221   { 0xEF, "unknown-0xEF" },
14222   { 0xF0, "unknown-0xF0" },
14223   { 0xF1, "unknown-0xF1" },
14224   { 0xF2, "unknown-0xF2" },
14225   { 0xF3, "unknown-0xF3" },
14226   { 0xF4, "unknown-0xF4" },
14227   { 0xF5, "unknown-0xF5" },
14228   { 0xF6, "unknown-0xF6" },
14229   { 0xF7, "unknown-0xF7" },
14230   { 0xF8, "unknown-0xF8" },
14231   { 0xF9, "unknown-0xF9" },
14232   { 0xFA, "unknown-0xFA" },
14233   { 0xFB, "unknown-0xFB" },
14234   { 0xFC, "unknown-0xFC" },
14235   { 0xFD, "unknown-0xFD" },
14236   { 0xFE, "SMBinvalid" },
14237   { 0xFF, "unknown-0xFF" },
14238   { 0x00, NULL },
14239 };
14240
14241 static char *decode_smb_name(unsigned char cmd)
14242 {
14243   return(smb_cmd_vals[cmd].strptr);
14244 }
14245
14246
14247
14248 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14249  * Everything TVBUFFIFIED above this line
14250  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14251
14252
14253 static void
14254 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14255 {
14256         conv_tables_t *ct = ctarg;
14257
14258         if (ct->unmatched)
14259                 g_hash_table_destroy(ct->unmatched);
14260         if (ct->matched)
14261                 g_hash_table_destroy(ct->matched);
14262         if (ct->dcerpc_fid_to_frame)
14263                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
14264         if (ct->dcerpc_frame_to_dcerpc_pdu)
14265                 g_hash_table_destroy(ct->dcerpc_frame_to_dcerpc_pdu);
14266         if (ct->tid_service)
14267                 g_hash_table_destroy(ct->tid_service);
14268 }
14269
14270 static void
14271 smb_init_protocol(void)
14272 {
14273         if (smb_saved_info_key_chunk)
14274                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14275         if (smb_saved_info_chunk)
14276                 g_mem_chunk_destroy(smb_saved_info_chunk);
14277         if (smb_nt_transact_info_chunk)
14278                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14279         if (smb_transact2_info_chunk)
14280                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14281         if (smb_transact_info_chunk)
14282                 g_mem_chunk_destroy(smb_transact_info_chunk);
14283
14284         /*
14285          * Free the hash tables attached to the conversation table
14286          * structures, and then free the list of conversation table
14287          * data structures (which doesn't free the data structures
14288          * themselves; that's done by destroying the chunk from
14289          * which they were allocated).
14290          */
14291         if (conv_tables) {
14292                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14293                 g_slist_free(conv_tables);
14294                 conv_tables = NULL;
14295         }
14296
14297         /*
14298          * Now destroy the chunk from which the conversation table
14299          * structures were allocated.
14300          */
14301         if (conv_tables_chunk)
14302                 g_mem_chunk_destroy(conv_tables_chunk);
14303
14304         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14305             sizeof(smb_saved_info_t),
14306             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14307             G_ALLOC_ONLY);
14308         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14309             sizeof(smb_saved_info_key_t),
14310             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14311             G_ALLOC_ONLY);
14312         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14313             sizeof(smb_nt_transact_info_t),
14314             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14315             G_ALLOC_ONLY);
14316         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14317             sizeof(smb_transact2_info_t),
14318             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14319             G_ALLOC_ONLY);
14320         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14321             sizeof(smb_transact_info_t),
14322             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14323             G_ALLOC_ONLY);
14324         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14325             sizeof(conv_tables_t),
14326             conv_tables_count * sizeof(conv_tables_t),
14327             G_ALLOC_ONLY);
14328 }
14329
14330 static const value_string errcls_types[] = {
14331   { SMB_SUCCESS, "Success"},
14332   { SMB_ERRDOS, "DOS Error"},
14333   { SMB_ERRSRV, "Server Error"},
14334   { SMB_ERRHRD, "Hardware Error"},
14335   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14336   { 0, NULL }
14337 };
14338
14339 const value_string DOS_errors[] = {
14340   {0, "Success"},
14341   {SMBE_insufficientbuffer, "Insufficient buffer"},
14342   {SMBE_badfunc, "Invalid function (or system call)"},
14343   {SMBE_badfile, "File not found (pathname error)"},
14344   {SMBE_badpath, "Directory not found"},
14345   {SMBE_nofids, "Too many open files"},
14346   {SMBE_noaccess, "Access denied"},
14347   {SMBE_badfid, "Invalid fid"},
14348   {SMBE_nomem,  "Out of memory"},
14349   {SMBE_badmem, "Invalid memory block address"},
14350   {SMBE_badenv, "Invalid environment"},
14351   {SMBE_badaccess, "Invalid open mode"},
14352   {SMBE_baddata, "Invalid data (only from ioctl call)"},
14353   {SMBE_res, "Reserved error code?"},
14354   {SMBE_baddrive, "Invalid drive"},
14355   {SMBE_remcd, "Attempt to delete current directory"},
14356   {SMBE_diffdevice, "Rename/move across different filesystems"},
14357   {SMBE_nofiles, "No more files found in file search"},
14358   {SMBE_badshare, "Share mode on file conflict with open mode"},
14359   {SMBE_lock, "Lock request conflicts with existing lock"},
14360   {SMBE_unsup, "Request unsupported, returned by Win 95"},
14361   {SMBE_nosuchshare, "Requested share does not exist"},
14362   {SMBE_filexists, "File in operation already exists"},
14363   {SMBE_cannotopen, "Cannot open the file specified"},
14364   {SMBE_unknownlevel, "Unknown info level"},
14365   {SMBE_invalidname, "Invalid name"},
14366   {SMBE_badpipe, "Named pipe invalid"},
14367   {SMBE_pipebusy, "All instances of pipe are busy"},
14368   {SMBE_pipeclosing, "Named pipe close in progress"},
14369   {SMBE_notconnected, "No process on other end of named pipe"},
14370   {SMBE_moredata, "More data to be returned"},
14371   {SMBE_baddirectory,  "Invalid directory name in a path."},
14372   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
14373   {SMBE_eas_nsup, "Extended attributes not supported"},
14374   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
14375   {SMBE_unknownipc, "Unknown IPC Operation"},
14376   {SMBE_noipc, "Don't support ipc"},
14377   {SMBE_alreadyexists, "File already exists"},
14378   {SMBE_unknownprinterdriver, "Unknown printer driver"},
14379   {SMBE_invalidprintername, "Invalid printer name"},
14380   {SMBE_printeralreadyexists, "Printer already exists"},
14381   {SMBE_invaliddatatype, "Invalid data type"},
14382   {SMBE_invalidenvironment, "Invalid environment"},
14383   {SMBE_printerdriverinuse, "Printer driver in use"},
14384   {SMBE_invalidparam, "Invalid parameter"},
14385   {SMBE_invalidformsize, "Invalid form size"},
14386   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
14387   {SMBE_invalidowner, "Invalid owner"},
14388   {SMBE_nomoreitems, "No more items"},
14389   {SMBE_serverunavailable, "Server unavailable"},
14390   {0, NULL}
14391   };
14392
14393 /* Error codes for the ERRSRV class */
14394
14395 static const value_string SRV_errors[] = {
14396   {SMBE_error, "Non specific error code"},
14397   {SMBE_badpw, "Bad password"},
14398   {SMBE_badtype, "Reserved"},
14399   {SMBE_access, "No permissions to perform the requested operation"},
14400   {SMBE_invnid, "TID invalid"},
14401   {SMBE_invnetname, "Invalid network name. Service not found"},
14402   {SMBE_invdevice, "Invalid device"},
14403   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14404   {SMBE_qfull, "Print queue full"},
14405   {SMBE_qtoobig, "Queued item too big"},
14406   {SMBE_qeof, "EOF on print queue dump"},
14407   {SMBE_invpfid, "Invalid print file in smb_fid"},
14408   {SMBE_smbcmd, "Unrecognised command"},
14409   {SMBE_srverror, "SMB server internal error"},
14410   {SMBE_filespecs, "Fid and pathname invalid combination"},
14411   {SMBE_badlink, "Bad link in request ???"},
14412   {SMBE_badpermits, "Access specified for a file is not valid"},
14413   {SMBE_badpid, "Bad process id in request"},
14414   {SMBE_setattrmode, "Attribute mode invalid"},
14415   {SMBE_paused, "Message server paused"},
14416   {SMBE_msgoff, "Not receiving messages"},
14417   {SMBE_noroom, "No room for message"},
14418   {SMBE_rmuns, "Too many remote usernames"},
14419   {SMBE_timeout, "Operation timed out"},
14420   {SMBE_noresource, "No resources currently available for request."},
14421   {SMBE_toomanyuids, "Too many userids"},
14422   {SMBE_baduid, "Bad userid"},
14423   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14424   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14425   {SMBE_contMPX, "Resume MPX mode"},
14426   {SMBE_badPW, "Bad Password???"},
14427   {SMBE_nosupport, "Operation not supported"},
14428   { 0, NULL}
14429 };
14430
14431 /* Error codes for the ERRHRD class */
14432
14433 static const value_string HRD_errors[] = {
14434   {SMBE_nowrite, "Read only media"},
14435   {SMBE_badunit, "Unknown device"},
14436   {SMBE_notready, "Drive not ready"},
14437   {SMBE_badcmd, "Unknown command"},
14438   {SMBE_data, "Data (CRC) error"},
14439   {SMBE_badreq, "Bad request structure length"},
14440   {SMBE_seek, "Seek error"},
14441   {SMBE_badmedia, "Unknown media type"},
14442   {SMBE_badsector, "Sector not found"},
14443   {SMBE_nopaper, "Printer out of paper"},
14444   {SMBE_write, "Write fault"},
14445   {SMBE_read, "Read fault"},
14446   {SMBE_general, "General failure"},
14447   {SMBE_badshare, "A open conflicts with an existing open"},
14448   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14449   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14450   {SMBE_FCBunavail, "No FCBs are available to process request"},
14451   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14452   {SMBE_diskfull, "Disk full???"},
14453   {0, NULL}
14454 };
14455
14456 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14457 {
14458
14459   switch (errcls) {
14460
14461   case SMB_SUCCESS:
14462
14463     return("No Error");   /* No error ??? */
14464     break;
14465
14466   case SMB_ERRDOS:
14467
14468     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14469     break;
14470
14471   case SMB_ERRSRV:
14472
14473     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14474     break;
14475
14476   case SMB_ERRHRD:
14477
14478     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14479     break;
14480
14481   default:
14482
14483     return("Unknown error class!");
14484
14485   }
14486
14487 }
14488
14489
14490 /* These are the MS country codes from
14491
14492         http://www.unicode.org/unicode/onlinedat/countries.html
14493
14494    For countries that share the same number, I choose to use only the
14495    name of the largest country. Apologies for this. If this offends you,
14496    here is the table to change that.
14497
14498    This also includes the code of 0 for "Default", which isn't in
14499    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14500    header file.  Presumably it means "don't override the setting
14501    on the user's machine".
14502
14503    Future versions of Microsoft's "winnls.h" header file might include
14504    additional codes; the current version matches the Unicode Consortium's
14505    table.
14506 */
14507 const value_string ms_country_codes[] = {
14508         {  0,   "Default"},
14509         {  1,   "USA"},
14510         {  2,   "Canada"},
14511         {  7,   "Russia"},
14512         { 20,   "Egypt"},
14513         { 27,   "South Africa"},
14514         { 30,   "Greece"},
14515         { 31,   "Netherlands"},
14516         { 32,   "Belgium"},
14517         { 33,   "France"},
14518         { 34,   "Spain"},
14519         { 36,   "Hungary"},
14520         { 39,   "Italy"},
14521         { 40,   "Romania"},
14522         { 41,   "Switzerland"},
14523         { 43,   "Austria"},
14524         { 44,   "United Kingdom"},
14525         { 45,   "Denmark"},
14526         { 46,   "Sweden"},
14527         { 47,   "Norway"},
14528         { 48,   "Poland"},
14529         { 49,   "Germany"},
14530         { 51,   "Peru"},
14531         { 52,   "Mexico"},
14532         { 54,   "Argentina"},
14533         { 55,   "Brazil"},
14534         { 56,   "Chile"},
14535         { 57,   "Colombia"},
14536         { 58,   "Venezuela"},
14537         { 60,   "Malaysia"},
14538         { 61,   "Australia"},
14539         { 62,   "Indonesia"},
14540         { 63,   "Philippines"},
14541         { 64,   "New Zealand"},
14542         { 65,   "Singapore"},
14543         { 66,   "Thailand"},
14544         { 81,   "Japan"},
14545         { 82,   "South Korea"},
14546         { 84,   "Viet Nam"},
14547         { 86,   "China"},
14548         { 90,   "Turkey"},
14549         { 91,   "India"},
14550         { 92,   "Pakistan"},
14551         {212,   "Morocco"},
14552         {213,   "Algeria"},
14553         {216,   "Tunisia"},
14554         {218,   "Libya"},
14555         {254,   "Kenya"},
14556         {263,   "Zimbabwe"},
14557         {298,   "Faroe Islands"},
14558         {351,   "Portugal"},
14559         {352,   "Luxembourg"},
14560         {353,   "Ireland"},
14561         {354,   "Iceland"},
14562         {355,   "Albania"},
14563         {358,   "Finland"},
14564         {359,   "Bulgaria"},
14565         {370,   "Lithuania"},
14566         {371,   "Latvia"},
14567         {372,   "Estonia"},
14568         {374,   "Armenia"},
14569         {375,   "Belarus"},
14570         {380,   "Ukraine"},
14571         {381,   "Serbia"},
14572         {385,   "Croatia"},
14573         {386,   "Slovenia"},
14574         {389,   "Macedonia"},
14575         {420,   "Czech Republic"},
14576         {421,   "Slovak Republic"},
14577         {501,   "Belize"},
14578         {502,   "Guatemala"},
14579         {503,   "El Salvador"},
14580         {504,   "Honduras"},
14581         {505,   "Nicaragua"},
14582         {506,   "Costa Rica"},
14583         {507,   "Panama"},
14584         {591,   "Bolivia"},
14585         {593,   "Ecuador"},
14586         {595,   "Paraguay"},
14587         {598,   "Uruguay"},
14588         {673,   "Brunei Darussalam"},
14589         {852,   "Hong Kong"},
14590         {853,   "Macau"},
14591         {886,   "Taiwan"},
14592         {960,   "Maldives"},
14593         {961,   "Lebanon"},
14594         {962,   "Jordan"},
14595         {963,   "Syria"},
14596         {964,   "Iraq"},
14597         {965,   "Kuwait"},
14598         {966,   "Saudi Arabia"},
14599         {967,   "Yemen"},
14600         {968,   "Oman"},
14601         {971,   "United Arab Emirates"},
14602         {972,   "Israel"},
14603         {973,   "Bahrain"},
14604         {974,   "Qatar"},
14605         {976,   "Mongolia"},
14606         {981,   "Iran"},
14607         {994,   "Azerbaijan"},
14608         {995,   "Georgia"},
14609         {996,   "Kyrgyzstan"},
14610
14611         {0,     NULL}
14612 };
14613
14614 /*
14615  * NT error codes.
14616  *
14617  * From
14618  *
14619  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14620  */
14621 const value_string NT_errors[] = {
14622   { 0x00000000, "STATUS_SUCCESS" },
14623   { 0x00000000, "STATUS_WAIT_0" },
14624   { 0x00000001, "STATUS_WAIT_1" },
14625   { 0x00000002, "STATUS_WAIT_2" },
14626   { 0x00000003, "STATUS_WAIT_3" },
14627   { 0x0000003F, "STATUS_WAIT_63" },
14628   { 0x00000080, "STATUS_ABANDONED" },
14629   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14630   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14631   { 0x000000C0, "STATUS_USER_APC" },
14632   { 0x00000100, "STATUS_KERNEL_APC" },
14633   { 0x00000101, "STATUS_ALERTED" },
14634   { 0x00000102, "STATUS_TIMEOUT" },
14635   { 0x00000103, "STATUS_PENDING" },
14636   { 0x00000104, "STATUS_REPARSE" },
14637   { 0x00000105, "STATUS_MORE_ENTRIES" },
14638   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14639   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14640   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14641   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14642   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14643   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14644   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14645   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14646   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14647   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14648   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14649   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14650   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14651   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14652   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14653   { 0x00000116, "STATUS_CRASH_DUMP" },
14654   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14655   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14656   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14657   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14658   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14659   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14660   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14661   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14662   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14663   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14664   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14665   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14666   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14667   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14668   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14669   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14670   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14671   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14672   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14673   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14674   { 0x40000012, "STATUS_EVENT_DONE" },
14675   { 0x40000013, "STATUS_EVENT_PENDING" },
14676   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14677   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14678   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14679   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14680   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14681   { 0x40000019, "STATUS_WAS_LOCKED" },
14682   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14683   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14684   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14685   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14686   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14687   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14688   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14689   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14690   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14691   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14692   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14693   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14694   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14695   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14696   { 0x80000003, "STATUS_BREAKPOINT" },
14697   { 0x80000004, "STATUS_SINGLE_STEP" },
14698   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14699   { 0x80000006, "STATUS_NO_MORE_FILES" },
14700   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14701   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14702   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14703   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14704   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14705   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14706   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14707   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14708   { 0x80000011, "STATUS_DEVICE_BUSY" },
14709   { 0x80000012, "STATUS_NO_MORE_EAS" },
14710   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14711   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14712   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14713   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14714   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14715   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14716   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14717   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14718   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14719   { 0x8000001D, "STATUS_BUS_RESET" },
14720   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14721   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14722   { 0x80000020, "STATUS_MEDIA_CHECK" },
14723   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14724   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14725   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14726   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14727   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14728   { 0x80000026, "STATUS_LONGJUMP" },
14729   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14730   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14731   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14732   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14733   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14734   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14735   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14736   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14737   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14738   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14739   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14740   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14741   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14742   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14743   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14744   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14745   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14746   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14747   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14748   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14749   { 0xC000000B, "STATUS_INVALID_CID" },
14750   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14751   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14752   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14753   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14754   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14755   { 0xC0000011, "STATUS_END_OF_FILE" },
14756   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14757   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14758   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14759   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14760   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14761   { 0xC0000017, "STATUS_NO_MEMORY" },
14762   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14763   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14764   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14765   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14766   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14767   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14768   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14769   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14770   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14771   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14772   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14773   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14774   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14775   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14776   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14777   { 0xC0000027, "STATUS_UNWIND" },
14778   { 0xC0000028, "STATUS_BAD_STACK" },
14779   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14780   { 0xC000002A, "STATUS_NOT_LOCKED" },
14781   { 0xC000002B, "STATUS_PARITY_ERROR" },
14782   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14783   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14784   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14785   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14786   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14787   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14788   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14789   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14790   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14791   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14792   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14793   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14794   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14795   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14796   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14797   { 0xC000003C, "STATUS_DATA_OVERRUN" },
14798   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
14799   { 0xC000003E, "STATUS_DATA_ERROR" },
14800   { 0xC000003F, "STATUS_CRC_ERROR" },
14801   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
14802   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
14803   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
14804   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
14805   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
14806   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
14807   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
14808   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
14809   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
14810   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
14811   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
14812   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
14813   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
14814   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
14815   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
14816   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
14817   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
14818   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
14819   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
14820   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
14821   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
14822   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
14823   { 0xC0000056, "STATUS_DELETE_PENDING" },
14824   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
14825   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
14826   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
14827   { 0xC000005A, "STATUS_INVALID_OWNER" },
14828   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
14829   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
14830   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
14831   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
14832   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
14833   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
14834   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
14835   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
14836   { 0xC0000063, "STATUS_USER_EXISTS" },
14837   { 0xC0000064, "STATUS_NO_SUCH_USER" },
14838   { 0xC0000065, "STATUS_GROUP_EXISTS" },
14839   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
14840   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
14841   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
14842   { 0xC0000069, "STATUS_LAST_ADMIN" },
14843   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
14844   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
14845   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
14846   { 0xC000006D, "STATUS_LOGON_FAILURE" },
14847   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
14848   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
14849   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
14850   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
14851   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
14852   { 0xC0000073, "STATUS_NONE_MAPPED" },
14853   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
14854   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
14855   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
14856   { 0xC0000077, "STATUS_INVALID_ACL" },
14857   { 0xC0000078, "STATUS_INVALID_SID" },
14858   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
14859   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
14860   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
14861   { 0xC000007C, "STATUS_NO_TOKEN" },
14862   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
14863   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
14864   { 0xC000007F, "STATUS_DISK_FULL" },
14865   { 0xC0000080, "STATUS_SERVER_DISABLED" },
14866   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
14867   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
14868   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
14869   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
14870   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
14871   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
14872   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
14873   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
14874   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
14875   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
14876   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
14877   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
14878   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
14879   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
14880   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
14881   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
14882   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
14883   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
14884   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
14885   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
14886   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
14887   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
14888   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
14889   { 0xC0000098, "STATUS_FILE_INVALID" },
14890   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
14891   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
14892   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
14893   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
14894   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
14895   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
14896   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
14897   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
14898   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
14899   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
14900   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
14901   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
14902   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
14903   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
14904   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
14905   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
14906   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
14907   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
14908   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
14909   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
14910   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
14911   { 0xC00000AE, "STATUS_PIPE_BUSY" },
14912   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
14913   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
14914   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
14915   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
14916   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
14917   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
14918   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
14919   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
14920   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
14921   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
14922   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
14923   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
14924   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
14925   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
14926   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
14927   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
14928   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
14929   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
14930   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
14931   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
14932   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
14933   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
14934   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
14935   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
14936   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
14937   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
14938   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
14939   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
14940   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
14941   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
14942   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
14943   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
14944   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
14945   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
14946   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
14947   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
14948   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
14949   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
14950   { 0xC00000D5, "STATUS_FILE_RENAMED" },
14951   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
14952   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
14953   { 0xC00000D8, "STATUS_CANT_WAIT" },
14954   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
14955   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
14956   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
14957   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
14958   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
14959   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
14960   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
14961   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
14962   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
14963   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
14964   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
14965   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
14966   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
14967   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
14968   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
14969   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
14970   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
14971   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
14972   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
14973   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
14974   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
14975   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
14976   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
14977   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
14978   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
14979   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
14980   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
14981   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
14982   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
14983   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
14984   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
14985   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
14986   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
14987   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
14988   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
14989   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
14990   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
14991   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
14992   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
14993   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
14994   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
14995   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
14996   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
14997   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
14998   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
14999   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15000   { 0xC0000107, "STATUS_FILES_OPEN" },
15001   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15002   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15003   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15004   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15005   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15006   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15007   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15008   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15009   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15010   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15011   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15012   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15013   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15014   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15015   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15016   { 0xC0000117, "STATUS_NO_LDT" },
15017   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15018   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15019   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15020   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15021   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15022   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15023   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15024   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15025   { 0xC0000120, "STATUS_CANCELLED" },
15026   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15027   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15028   { 0xC0000123, "STATUS_FILE_DELETED" },
15029   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15030   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15031   { 0xC0000126, "STATUS_SPECIAL_USER" },
15032   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15033   { 0xC0000128, "STATUS_FILE_CLOSED" },
15034   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15035   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15036   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15037   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15038   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15039   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15040   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15041   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15042   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15043   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15044   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15045   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15046   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15047   { 0xC0000136, "STATUS_OPEN_FAILED" },
15048   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15049   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15050   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15051   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15052   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15053   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15054   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15055   { 0xC000013E, "STATUS_LINK_FAILED" },
15056   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15057   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15058   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15059   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15060   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15061   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15062   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15063   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15064   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15065   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15066   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15067   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15068   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15069   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15070   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15071   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15072   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15073   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15074   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15075   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15076   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15077   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15078   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15079   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15080   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15081   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15082   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15083   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15084   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15085   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15086   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15087   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15088   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15089   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15090   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15091   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15092   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15093   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15094   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15095   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15096   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15097   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15098   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15099   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15100   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15101   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15102   { 0xC000016D, "STATUS_FT_ORPHANING" },
15103   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15104   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15105   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15106   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15107   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15108   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15109   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15110   { 0xC0000178, "STATUS_NO_MEDIA" },
15111   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15112   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15113   { 0xC000017C, "STATUS_KEY_DELETED" },
15114   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15115   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15116   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15117   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15118   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15119   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15120   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15121   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15122   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15123   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15124   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15125   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15126   { 0xC0000189, "STATUS_TOO_LATE" },
15127   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15128   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15129   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15130   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15131   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15132   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15133   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15134   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15135   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15136   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15137   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15138   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15139   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15140   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15141   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15142   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15143   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15144   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15145   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15146   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15147   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15148   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15149   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15150   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15151   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15152   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15153   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15154   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15155   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15156   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15157   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15158   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15159   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15160   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15161   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15162   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15163   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15164   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15165   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15166   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15167   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15168   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15169   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15170   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15171   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15172   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15173   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15174   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15175   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15176   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15177   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15178   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15179   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15180   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15181   { 0xC0000225, "STATUS_NOT_FOUND" },
15182   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15183   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15184   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15185   { 0xC0000229, "STATUS_FAIL_CHECK" },
15186   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15187   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15188   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15189   { 0xC000022D, "STATUS_RETRY" },
15190   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15191   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15192   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15193   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15194   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15195   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15196   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15197   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15198   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15199   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15200   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15201   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15202   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15203   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15204   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15205   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15206   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15207   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15208   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15209   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15210   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15211   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15212   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15213   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15214   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15215   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15216   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15217   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15218   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15219   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15220   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15221   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15222   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15223   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15224   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15225   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15226   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15227   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15228   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15229   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15230   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15231   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15232   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15233   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15234   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15235   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15236   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15237   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15238   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15239   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15240   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15241   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15242   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15243   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15244   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15245   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15246   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15247   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15248   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15249   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15250   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15251   { 0xC0000272, "STATUS_NO_MATCH" },
15252   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15253   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15254   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15255   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15256   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15257   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15258   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15259   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15260   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15261   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15262   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15263   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15264   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15265   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15266   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15267   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15268   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15269   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15270   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15271   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15272   { 0xC000028E, "STATUS_NO_EFS" },
15273   { 0xC000028F, "STATUS_WRONG_EFS" },
15274   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15275   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15276   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15277   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15278   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15279   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15280   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15281   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15282   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15283   { 0xC0000299, "STATUS_SHARED_POLICY" },
15284   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15285   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15286   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15287   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15288   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15289   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15290   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15291   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15292   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15293   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15294   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15295   { 0xC00002A5, "STATUS_DS_BUSY" },
15296   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15297   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15298   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15299   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15300   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15301   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15302   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15303   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15304   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15305   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15306   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15307   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15308   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15309   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15310   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15311   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15312   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15313   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15314   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15315   { 0xC00002B9, "STATUS_NOINTERFACE" },
15316   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15317   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15318   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15319   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15320   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15321   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15322   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15323   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15324   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15325   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15326   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15327   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15328   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15329   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15330   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15331   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15332   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15333   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15334   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15335   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15336   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15337   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
15338   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
15339   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
15340   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
15341   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
15342   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
15343   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
15344   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
15345   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
15346   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
15347   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
15348   { 0xC00002E1, "STATUS_DS_CANT_START" },
15349   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
15350   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
15351   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
15352   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
15353   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
15354   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
15355   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
15356   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
15357   { 0xC0009898, "STATUS_WOW_ASSERTION" },
15358   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
15359   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
15360   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
15361   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
15362   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
15363   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
15364   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
15365   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
15366   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
15367   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
15368   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
15369   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
15370   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
15371   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
15372   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
15373   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
15374   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
15375   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
15376   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
15377   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
15378   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
15379   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
15380   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
15381   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
15382   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
15383   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
15384   { 0xC002001B, "RPC_NT_CALL_FAILED" },
15385   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
15386   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
15387   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
15388   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
15389   { 0xC0020022, "RPC_NT_INVALID_TAG" },
15390   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
15391   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
15392   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
15393   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
15394   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
15395   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
15396   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
15397   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
15398   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
15399   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
15400   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
15401   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
15402   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
15403   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
15404   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
15405   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
15406   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
15407   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
15408   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
15409   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
15410   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
15411   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
15412   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
15413   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
15414   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
15415   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
15416   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
15417   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
15418   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
15419   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
15420   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
15421   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
15422   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
15423   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
15424   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
15425   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
15426   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
15427   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
15428   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
15429   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
15430   { 0xC002100A, "RPC_P_SEND_FAILED" },
15431   { 0xC002100B, "RPC_P_TIMEOUT" },
15432   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
15433   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
15434   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
15435   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
15436   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
15437   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
15438   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
15439   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
15440   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
15441   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
15442   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
15443   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
15444   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
15445   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
15446   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
15447   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
15448   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
15449   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
15450   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
15451   { 0xC002004C, "EPT_NT_CANT_CREATE" },
15452   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
15453   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
15454   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
15455   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
15456   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
15457   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
15458   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15459   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15460   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15461   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15462   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15463   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15464   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15465   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15466   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15467   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15468   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15469   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15470   { 0,          NULL }
15471 };
15472
15473
15474
15475 static const true_false_string tfs_smb_flags_lock = {
15476         "Lock&Read, Write&Unlock are supported",
15477         "Lock&Read, Write&Unlock are not supported"
15478 };
15479 static const true_false_string tfs_smb_flags_receive_buffer = {
15480         "Receive buffer has been posted",
15481         "Receive buffer has not been posted"
15482 };
15483 static const true_false_string tfs_smb_flags_caseless = {
15484         "Path names are caseless",
15485         "Path names are case sensitive"
15486 };
15487 static const true_false_string tfs_smb_flags_canon = {
15488         "Pathnames are canonicalized",
15489         "Pathnames are not canonicalized"
15490 };
15491 static const true_false_string tfs_smb_flags_oplock = {
15492         "OpLock requested/granted",
15493         "OpLock not requested/granted"
15494 };
15495 static const true_false_string tfs_smb_flags_notify = {
15496         "Notify client on all modifications",
15497         "Notify client only on open"
15498 };
15499 static const true_false_string tfs_smb_flags_response = {
15500         "Message is a response to the client/redirector",
15501         "Message is a request to the server"
15502 };
15503
15504 static int
15505 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15506 {
15507         guint8 mask;
15508         proto_item *item = NULL;
15509         proto_tree *tree = NULL;
15510
15511         mask = tvb_get_guint8(tvb, offset);
15512
15513         if(parent_tree){
15514                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15515                         "Flags: 0x%02x", mask);
15516                 tree = proto_item_add_subtree(item, ett_smb_flags);
15517         }
15518         proto_tree_add_boolean(tree, hf_smb_flags_response,
15519                 tvb, offset, 1, mask);
15520         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15521                 tvb, offset, 1, mask);
15522         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15523                 tvb, offset, 1, mask);
15524         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15525                 tvb, offset, 1, mask);
15526         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15527                 tvb, offset, 1, mask);
15528         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15529                 tvb, offset, 1, mask);
15530         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15531                 tvb, offset, 1, mask);
15532         offset += 1;
15533         return offset;
15534 }
15535
15536
15537
15538 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15539         "Long file names are allowed in the response",
15540         "Long file names are not allowed in the response"
15541 };
15542 static const true_false_string tfs_smb_flags2_ea = {
15543         "Extended attributes are supported",
15544         "Extended attributes are not supported"
15545 };
15546 static const true_false_string tfs_smb_flags2_sec_sig = {
15547         "Security signatures are supported",
15548         "Security signatures are not supported"
15549 };
15550 static const true_false_string tfs_smb_flags2_long_names_used = {
15551         "Path names in request are long file names",
15552         "Path names in request are not long file names"
15553 };
15554 static const true_false_string tfs_smb_flags2_esn = {
15555         "Extended security negotiation is supported",
15556         "Extended security negotiation is not supported"
15557 };
15558 static const true_false_string tfs_smb_flags2_dfs = {
15559         "Resolve pathnames with Dfs",
15560         "Don't resolve pathnames with Dfs"
15561 };
15562 static const true_false_string tfs_smb_flags2_roe = {
15563         "Permit reads if execute-only",
15564         "Don't permit reads if execute-only"
15565 };
15566 static const true_false_string tfs_smb_flags2_nt_error = {
15567         "Error codes are NT error codes",
15568         "Error codes are DOS error codes"
15569 };
15570 static const true_false_string tfs_smb_flags2_string = {
15571         "Strings are Unicode",
15572         "Strings are ASCII"
15573 };
15574 static int
15575 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15576 {
15577         guint16 mask;
15578         proto_item *item = NULL;
15579         proto_tree *tree = NULL;
15580
15581         mask = tvb_get_letohs(tvb, offset);
15582
15583         if(parent_tree){
15584                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15585                         "Flags2: 0x%04x", mask);
15586                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15587         }
15588
15589         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15590                 tvb, offset, 2, mask);
15591         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15592                 tvb, offset, 2, mask);
15593         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15594                 tvb, offset, 2, mask);
15595         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15596                 tvb, offset, 2, mask);
15597         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15598                 tvb, offset, 2, mask);
15599         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15600                 tvb, offset, 2, mask);
15601         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15602                 tvb, offset, 2, mask);
15603         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15604                 tvb, offset, 2, mask);
15605         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15606                 tvb, offset, 2, mask);
15607
15608         offset += 2;
15609         return offset;
15610 }
15611
15612
15613
15614 #define SMB_FLAGS_DIRN 0x80
15615
15616
15617 static void
15618 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15619 {
15620         int offset = 0;
15621         proto_item *item = NULL, *hitem = NULL;
15622         proto_tree *tree = NULL, *htree = NULL;
15623         guint8          flags;
15624         guint16         flags2;
15625         static smb_info_t       si_arr[20];
15626         static int si_counter=0;
15627         smb_info_t              *si;
15628         smb_saved_info_t *sip = NULL;
15629         smb_saved_info_key_t key;
15630         smb_saved_info_key_t *new_key;
15631         guint32 nt_status = 0;
15632         guint8 errclass = 0;
15633         guint16 errcode = 0;
15634         guint32 pid_mid;
15635         conversation_t *conversation;
15636         nstime_t ns;
15637
15638         si_counter++;
15639         if(si_counter==20){
15640                 si_counter=0;
15641         }
15642         si=&si_arr[si_counter];
15643
15644         top_tree=parent_tree;
15645
15646         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15647                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15648         }
15649         if (check_col(pinfo->cinfo, COL_INFO)){
15650                 col_clear(pinfo->cinfo, COL_INFO);
15651         }
15652
15653         /* start off using the local variable, we will allocate a new one if we
15654            need to*/
15655         si->cmd = tvb_get_guint8(tvb, offset+4);
15656         flags = tvb_get_guint8(tvb, offset+9);
15657         /*
15658          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
15659          * the direction flag appears never to be set, even for what appear
15660          * to be replies.  Do some SMB servers fail to set that flag,
15661          * under the assumption that the client knows it's a reply because
15662          * it received it?
15663          */
15664         si->request = !(flags&SMB_FLAGS_DIRN);
15665         flags2 = tvb_get_letohs(tvb, offset+10);
15666         if(flags2 & 0x8000){
15667                 si->unicode = TRUE; /* Mark them as Unicode */
15668         } else {
15669                 si->unicode = FALSE;
15670         }
15671         si->tid = tvb_get_letohs(tvb, offset+24);
15672         si->pid = tvb_get_letohs(tvb, offset+26);
15673         si->uid = tvb_get_letohs(tvb, offset+28);
15674         si->mid = tvb_get_letohs(tvb, offset+30);
15675         pid_mid = (si->pid << 16) | si->mid;
15676         si->info_level = -1;
15677         si->info_count = -1;
15678
15679         if (parent_tree) {
15680                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
15681                         -1, FALSE);
15682                 tree = proto_item_add_subtree(item, ett_smb);
15683
15684                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
15685                         "SMB Header");
15686
15687                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15688         }
15689
15690         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15691         offset += 4;  /* Skip the marker */
15692
15693         /* find which conversation we are part of and get the tables for that
15694            conversation*/
15695         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15696                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15697         if(!conversation){
15698                 /* OK this is a new conversation so lets create it */
15699                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
15700                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15701         }
15702         /* see if we already have the smb data for this conversation */
15703         si->ct=conversation_get_proto_data(conversation, proto_smb);
15704         if(!si->ct){
15705                 /* No, not yet. create it and attach it to the conversation */
15706                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
15707                 conv_tables = g_slist_prepend(conv_tables, si->ct);
15708                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
15709                         smb_saved_info_equal_matched);
15710                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
15711                         smb_saved_info_equal_unmatched);
15712                 si->ct->dcerpc_fid_to_frame=g_hash_table_new(
15713                         smb_saved_info_hash_unmatched,
15714                         smb_saved_info_equal_unmatched);
15715                 si->ct->dcerpc_frame_to_dcerpc_pdu=g_hash_table_new(
15716                         smb_saved_info_hash_unmatched,
15717                         smb_saved_info_equal_unmatched);
15718                 si->ct->tid_service=g_hash_table_new(
15719                         smb_saved_info_hash_unmatched,
15720                         smb_saved_info_equal_unmatched);
15721                 conversation_add_proto_data(conversation, proto_smb, si->ct);
15722         }
15723
15724         if( (si->request)
15725             &&  (si->mid==0)
15726             &&  (si->uid==0)
15727             &&  (si->pid==0)
15728             &&  (si->tid==0) ){
15729                 /* this is a broadcast SMB packet, there will not be a reply.
15730                    We dont need to do anything
15731                 */
15732                 si->unidir = TRUE;
15733         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15734                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15735                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15736                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15737                 /* Ok, we got a special request type. This request is either
15738                    an NT Cancel or a continuation relative to a real request
15739                    in an earlier packet.  In either case, we don't expect any
15740                    responses to this packet.  For continuations, any later
15741                    responses we see really just belong to the original request.
15742                    Anyway, we want to remember this packet somehow and
15743                    remember which original request it is associated with so
15744                    we can say nice things such as "This is a Cancellation to
15745                    the request in frame x", but we don't want the
15746                    request/response matching to get messed up.
15747
15748                    The only thing we do in this case is trying to find which original
15749                    request we match with and insert an entry for this "special"
15750                    request for later reference. We continue to reference the original
15751                    requests smb_saved_info_t but we dont touch it or change anything
15752                    in it.
15753                 */
15754
15755                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
15756
15757                 if(!pinfo->fd->flags.visited){
15758                         /* try to find which original call we match and if we
15759                            find it add us to the matched table. Dont touch
15760                            anything else since we dont want this one to mess
15761                            up the request/response matching. We still consider
15762                            the initial call the real request and this is only
15763                            some sort of continuation.
15764                         */
15765                         /* we only check the unmatched table and assume that the
15766                            last seen MID matching ours is the right one.
15767                            This can fail but is better than nothing
15768                         */
15769                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
15770                         if(sip!=NULL){
15771                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15772                                 new_key->frame = pinfo->fd->num;
15773                                 new_key->pid_mid = pid_mid;
15774                                 g_hash_table_insert(si->ct->matched, new_key,
15775                                     sip);
15776                         }
15777                 } else {
15778                         /* we have seen this packet before; check the
15779                            matching table
15780                         */
15781                         key.frame = pinfo->fd->num;
15782                         key.pid_mid = pid_mid;
15783                         sip=g_hash_table_lookup(si->ct->matched, &key);
15784                         if(sip==NULL){
15785                         /*
15786                           We didn't find it.
15787                           Too bad, unfortunately there is not really much we can
15788                           do now since this means that we never saw the initial
15789                           request.
15790                          */
15791                         }
15792                 }
15793
15794
15795                 if(sip && sip->frame_req){
15796                         switch(si->cmd){
15797                         case SMB_COM_NT_CANCEL:
15798                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
15799                                                     tvb, 0, 0, sip->frame_req);
15800                                 break;
15801                         case SMB_COM_TRANSACTION_SECONDARY:
15802                         case SMB_COM_TRANSACTION2_SECONDARY:
15803                         case SMB_COM_NT_TRANSACT_SECONDARY:
15804                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
15805                                                     tvb, 0, 0, sip->frame_req);
15806                                 break;
15807                         }
15808                 } else {
15809                         switch(si->cmd){
15810                         case SMB_COM_NT_CANCEL:
15811                                 proto_tree_add_text(htree, tvb, 0, 0,
15812                                                     "Cancellation to: <unknown frame>");
15813                                 break;
15814                         case SMB_COM_TRANSACTION_SECONDARY:
15815                         case SMB_COM_TRANSACTION2_SECONDARY:
15816                         case SMB_COM_NT_TRANSACT_SECONDARY:
15817                                 proto_tree_add_text(htree, tvb, 0, 0,
15818                                                     "Continuation to: <unknown frame>");
15819                                 break;
15820                         }
15821                 }
15822         } else { /* normal bidirectional request or response */
15823                 si->unidir = FALSE;
15824
15825                 if(!pinfo->fd->flags.visited){
15826                         /* first see if we find an unmatched smb "equal" to
15827                            the current one
15828                         */
15829                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
15830                         if(sip!=NULL){
15831                                 gboolean cmd_match=FALSE;
15832
15833                                 /*
15834                                  * Make sure the SMB we found was the
15835                                  * same command, or a different command
15836                                  * that's another valid type of reply
15837                                  * to that command.
15838                                  */
15839                                 if(si->cmd==sip->cmd){
15840                                         cmd_match=TRUE;
15841                                 }
15842                                 else if(si->cmd==SMB_COM_NT_CANCEL){
15843                                         cmd_match=TRUE;
15844                                 }
15845                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
15846                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15847                                         cmd_match=TRUE;
15848                                 }
15849                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
15850                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15851                                         cmd_match=TRUE;
15852                                 }
15853                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
15854                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15855                                         cmd_match=TRUE;
15856                                 }
15857
15858                                 if( (si->request) || (!cmd_match) ) {
15859                                         /* If we are processing an SMB request but there was already
15860                                            another "identical" smb resuest we had not matched yet.
15861                                            This must mean that either we have a retransmission or that the
15862                                            response to the previous one was lost and the client has reused
15863                                            the MID for this conversation. In either case it's not much more
15864                                            we can do than forget the old request and concentrate on the
15865                                            present one instead.
15866
15867                                            We also do this cleanup if we see that the cmd in the original
15868                                            request in sip->cmd is not compatible with the current cmd.
15869                                            This is to prevent matching errors such as if there were two
15870                                            SMBs of different cmds but with identical MID and PID values and
15871                                            if ethereal lost the first reply and the second request.
15872                                         */
15873                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
15874                                         sip=NULL; /* XXX should free it as well */
15875                                 } else {
15876                                         /* we have found a response to some request we have seen earlier.
15877                                            What we do now depends on whether this is the first response
15878                                            to that request we see (id frame_res==0) or not.
15879                                         */
15880                                         if(sip->frame_res==0){
15881                                                 /* ok it is the first response we have seen to this packet */
15882                                                 sip->frame_res = pinfo->fd->num;
15883                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15884                                                 new_key->frame = sip->frame_res;
15885                                                 new_key->pid_mid = pid_mid;
15886                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15887                                         } else {
15888                                                 /* we have already seen another response to this one, but
15889                                                    register it anyway so we see which request it matches
15890                                                 */
15891                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15892                                                 new_key->frame = pinfo->fd->num;
15893                                                 new_key->pid_mid = pid_mid;
15894                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15895                                         }
15896                                 }
15897                         }
15898                         if(si->request){
15899                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
15900                                 sip->frame_req = pinfo->fd->num;
15901                                 sip->frame_res = 0;
15902                                 sip->req_time.secs=pinfo->fd->abs_secs;
15903                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
15904                                 sip->flags = 0;
15905                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
15906                                     == (void *)TID_IPC) {
15907                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15908                                 }
15909                                 sip->cmd = si->cmd;
15910                                 sip->extra_info = NULL;
15911                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
15912                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15913                                 new_key->frame = sip->frame_req;
15914                                 new_key->pid_mid = pid_mid;
15915                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15916                         }
15917                 } else {
15918                         /* we have seen this packet before; check the
15919                            matching table.
15920                            If we haven't yet seen the reply, we won't
15921                            find the info for it; we don't need it, as
15922                            we only use it to save information, and, as
15923                            we've seen this packet before, we've already
15924                            saved the information.
15925                         */
15926                         key.frame = pinfo->fd->num;
15927                         key.pid_mid = pid_mid;
15928                         sip=g_hash_table_lookup(si->ct->matched, &key);
15929                 }
15930         }
15931
15932         /*
15933          * Pass the "sip" on to subdissectors through "si".
15934          */
15935         si->sip = sip;
15936
15937         if (sip != NULL) {
15938                 /*
15939                  * Put in fields for the frame number of the frame to which
15940                  * this is a response or the frame with the response to this
15941                  * frame - if we know the frame number (i.e., it's not 0).
15942                  */
15943                 if(si->request){
15944                         if (sip->frame_res != 0)
15945                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15946                 } else {
15947                         if (sip->frame_req != 0) {
15948                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
15949                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
15950                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
15951                                 if(ns.nsecs<0){
15952                                         ns.nsecs+=1000000000;
15953                                         ns.secs--;
15954                                 }
15955                                 proto_tree_add_time(htree, hf_smb_time, tvb,
15956                                     0, 0, &ns);
15957                         }
15958                 }
15959         }
15960
15961         /* smb command */
15962         proto_tree_add_uint_format(htree, hf_smb_cmd, tvb, offset, 1, si->cmd, "SMB Command: %s (0x%02x)", decode_smb_name(si->cmd), si->cmd);
15963         offset += 1;
15964
15965         if(flags2 & 0x4000){
15966                 /* handle NT 32 bit error code */
15967
15968                 nt_status = tvb_get_letohl(tvb, offset);
15969
15970                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
15971                         TRUE);
15972                 offset += 4;
15973
15974         } else {
15975                 /* handle DOS error code & class */
15976                 errclass = tvb_get_guint8(tvb, offset);
15977                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
15978                         errclass);
15979                 offset += 1;
15980
15981                 /* reserved byte */
15982                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
15983                 offset += 1;
15984
15985                 /* error code */
15986                 /* XXX - the type of this field depends on the value of
15987                  * "errcls", so there is isn't a single value_string array
15988                  * fo it, so there can't be a single field for it.
15989                  */
15990                 errcode = tvb_get_letohs(tvb, offset);
15991                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
15992                         offset, 2, errcode, "Error Code: %s",
15993                         decode_smb_error(errclass, errcode));
15994                 offset += 2;
15995         }
15996
15997         /* flags */
15998         offset = dissect_smb_flags(tvb, htree, offset);
15999
16000         /* flags2 */
16001         offset = dissect_smb_flags2(tvb, htree, offset);
16002
16003         /*
16004          * The document at
16005          *
16006          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16007          *
16008          * (a text version of "Microsoft Networks SMB FILE SHARING
16009          * PROTOCOL, Document Version 6.0p") says that:
16010          *
16011          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16012          *      the "High Part of PID";
16013          *
16014          *      the next four bytes are reserved;
16015          *
16016          *      the next four bytes are, for SMB-over-IPX (with no
16017          *      NetBIOS involved) two bytes of Session ID and two bytes
16018          *      of SequenceNumber.
16019          *
16020          * Network Monitor 2.x dissects the four bytes before the Session ID
16021          * as a "Key", and the two bytes after the SequenceNumber as
16022          * a "Group ID".
16023          */
16024         if (pinfo->ptype == PT_IPX &&
16025             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16026              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16027              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16028                 /*
16029                  * This is SMB-over-IPX.
16030                  * XXX - high part of pid?
16031                  * XXX - doe we have to worry about "sequenced commands",
16032                  * as per the Samba document?  They say that for
16033                  * "unsequenced commands" (with a sequence number of 0),
16034                  * the Mid must be unique, but perhaps the Mid doesn't
16035                  * have to be unique for sequenced commands.  In at least
16036                  * one capture with SMB-over-IPX, however, the Mids
16037                  * are unique even for sequenced commands.
16038                  */
16039                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2,
16040                     TRUE);
16041                 offset += 2;
16042
16043                 /* Key */
16044                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16045                     TRUE);
16046                 offset += 4;
16047
16048                 /* Session ID */
16049                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16050                     TRUE);
16051                 offset += 2;
16052
16053                 /* Sequence number */
16054                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16055                     TRUE);
16056                 offset += 2;
16057
16058                 /* Group ID */
16059                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16060                     TRUE);
16061                 offset += 2;
16062         } else {
16063                 /*
16064                  * 12 reserved bytes.
16065                  * XXX - high part of pid?
16066                  */
16067                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
16068                 offset += 12;
16069         }
16070
16071         /* TID */
16072         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16073         offset += 2;
16074
16075         /* PID */
16076         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16077         offset += 2;
16078
16079         /* UID */
16080         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16081         offset += 2;
16082
16083         /* MID */
16084         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16085         offset += 2;
16086
16087         pinfo->private_data = si;
16088
16089         /* tap the packet before the dissectors are called so we still get
16090            the tap listener called even if there is an exception.
16091         */
16092         tap_queue_packet(smb_tap, pinfo, si);
16093         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16094
16095         /* Append error info from this packet to info string. */
16096         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16097                 if (flags2 & 0x4000) {
16098                         /*
16099                          * The status is an NT status code; was there
16100                          * an error?
16101                          */
16102                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16103                                 /*
16104                                  * Yes.
16105                                  */
16106                                 col_append_fstr(
16107                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16108                                         val_to_str(nt_status, NT_errors,
16109                                             "Unknown (0x%08X)"));
16110                         }
16111                 } else {
16112                         /*
16113                          * The status is a DOS error class and code; was
16114                          * there an error?
16115                          */
16116                         if (errclass != SMB_SUCCESS) {
16117                                 /*
16118                                  * Yes.
16119                                  */
16120                                 col_append_fstr(
16121                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16122                                         decode_smb_error(errclass, errcode));
16123                         }
16124                 }
16125         }
16126 }
16127
16128 static gboolean
16129 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16130 {
16131         /* must check that this really is a smb packet */
16132         if (!tvb_bytes_exist(tvb, 0, 4))
16133                 return FALSE;
16134
16135         if( (tvb_get_guint8(tvb, 0) != 0xff)
16136             || (tvb_get_guint8(tvb, 1) != 'S')
16137             || (tvb_get_guint8(tvb, 2) != 'M')
16138             || (tvb_get_guint8(tvb, 3) != 'B') ){
16139                 return FALSE;
16140         }
16141
16142         dissect_smb(tvb, pinfo, parent_tree);
16143         return TRUE;
16144 }
16145
16146 void
16147 proto_register_smb(void)
16148 {
16149         static hf_register_info hf[] = {
16150         { &hf_smb_cmd,
16151                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16152                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16153
16154         { &hf_smb_word_count,
16155                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16156                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16157
16158         { &hf_smb_byte_count,
16159                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16160                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16161
16162         { &hf_smb_response_to,
16163                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16164                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16165
16166         { &hf_smb_time,
16167                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16168                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16169
16170         { &hf_smb_response_in,
16171                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16172                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16173
16174         { &hf_smb_continuation_to,
16175                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16176                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16177
16178         { &hf_smb_nt_status,
16179                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16180                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16181
16182         { &hf_smb_error_class,
16183                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16184                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16185
16186         { &hf_smb_error_code,
16187                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16188                 NULL, 0, "DOS Error Code", HFILL }},
16189
16190         { &hf_smb_reserved,
16191                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16192                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16193
16194         { &hf_smb_key,
16195                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16196                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16197
16198         { &hf_smb_session_id,
16199                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16200                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16201
16202         { &hf_smb_sequence_num,
16203                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16204                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16205
16206         { &hf_smb_group_id,
16207                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16208                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16209
16210         { &hf_smb_pid,
16211                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16212                 NULL, 0, "Process ID", HFILL }},
16213
16214         { &hf_smb_tid,
16215                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16216                 NULL, 0, "Tree ID", HFILL }},
16217
16218         { &hf_smb_uid,
16219                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16220                 NULL, 0, "User ID", HFILL }},
16221
16222         { &hf_smb_mid,
16223                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16224                 NULL, 0, "Multiplex ID", HFILL }},
16225
16226         { &hf_smb_flags_lock,
16227                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16228                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16229
16230         { &hf_smb_flags_receive_buffer,
16231                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16232                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16233
16234         { &hf_smb_flags_caseless,
16235                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16236                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16237
16238         { &hf_smb_flags_canon,
16239                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16240                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16241
16242         { &hf_smb_flags_oplock,
16243                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16244                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16245
16246         { &hf_smb_flags_notify,
16247                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16248                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16249
16250         { &hf_smb_flags_response,
16251                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16252                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16253
16254         { &hf_smb_flags2_long_names_allowed,
16255                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16256                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16257
16258         { &hf_smb_flags2_ea,
16259                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16260                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16261
16262         { &hf_smb_flags2_sec_sig,
16263                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16264                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16265
16266         { &hf_smb_flags2_long_names_used,
16267                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16268                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16269
16270         { &hf_smb_flags2_esn,
16271                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16272                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16273
16274         { &hf_smb_flags2_dfs,
16275                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16276                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16277
16278         { &hf_smb_flags2_roe,
16279                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16280                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16281
16282         { &hf_smb_flags2_nt_error,
16283                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16284                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16285
16286         { &hf_smb_flags2_string,
16287                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16288                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16289
16290         { &hf_smb_buffer_format,
16291                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16292                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16293
16294         { &hf_smb_dialect_name,
16295                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16296                 NULL, 0, "Name of dialect", HFILL }},
16297
16298         { &hf_smb_dialect_index,
16299                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16300                 NULL, 0, "Index of selected dialect", HFILL }},
16301
16302         { &hf_smb_max_trans_buf_size,
16303                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16304                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16305
16306         { &hf_smb_max_mpx_count,
16307                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16308                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16309
16310         { &hf_smb_max_vcs_num,
16311                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16312                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16313
16314         { &hf_smb_session_key,
16315                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16316                 NULL, 0, "Unique token identifying this session", HFILL }},
16317
16318         { &hf_smb_server_timezone,
16319                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16320                 NULL, 0, "Current timezone at server.", HFILL }},
16321
16322         { &hf_smb_encryption_key_length,
16323                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16324                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16325
16326         { &hf_smb_encryption_key,
16327                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16328                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16329
16330         { &hf_smb_primary_domain,
16331                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16332                 NULL, 0, "The server's primary domain", HFILL }},
16333
16334         { &hf_smb_server,
16335                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16336                 NULL, 0, "The name of the DC/server", HFILL }},
16337
16338         { &hf_smb_max_raw_buf_size,
16339                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16340                 NULL, 0, "Maximum raw buffer size", HFILL }},
16341
16342         { &hf_smb_server_guid,
16343                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16344                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16345
16346         { &hf_smb_security_blob_len,
16347                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16348                 NULL, 0, "Security blob length", HFILL }},
16349
16350         { &hf_smb_security_blob,
16351                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16352                 NULL, 0, "Security blob", HFILL }},
16353
16354         { &hf_smb_sm_mode16,
16355                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16356                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16357
16358         { &hf_smb_sm_password16,
16359                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16360                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16361
16362         { &hf_smb_sm_mode,
16363                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16364                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16365
16366         { &hf_smb_sm_password,
16367                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16368                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16369
16370         { &hf_smb_sm_signatures,
16371                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16372                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16373
16374         { &hf_smb_sm_sig_required,
16375                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16376                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16377
16378         { &hf_smb_rm_read,
16379                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16380                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16381
16382         { &hf_smb_rm_write,
16383                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16384                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16385
16386         { &hf_smb_server_date_time,
16387                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16388                 NULL, 0, "Current date and time at server", HFILL }},
16389
16390         { &hf_smb_server_smb_date,
16391                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16392                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16393
16394         { &hf_smb_server_smb_time,
16395                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16396                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16397
16398         { &hf_smb_server_cap_raw_mode,
16399                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16400                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16401
16402         { &hf_smb_server_cap_mpx_mode,
16403                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16404                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16405
16406         { &hf_smb_server_cap_unicode,
16407                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16408                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16409
16410         { &hf_smb_server_cap_large_files,
16411                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16412                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16413
16414         { &hf_smb_server_cap_nt_smbs,
16415                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16416                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16417
16418         { &hf_smb_server_cap_rpc_remote_apis,
16419                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16420                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16421
16422         { &hf_smb_server_cap_nt_status,
16423                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16424                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16425
16426         { &hf_smb_server_cap_level_ii_oplocks,
16427                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16428                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16429
16430         { &hf_smb_server_cap_lock_and_read,
16431                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16432                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16433
16434         { &hf_smb_server_cap_nt_find,
16435                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16436                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16437
16438         { &hf_smb_server_cap_dfs,
16439                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16440                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16441
16442         { &hf_smb_server_cap_infolevel_passthru,
16443                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16444                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16445
16446         { &hf_smb_server_cap_large_readx,
16447                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16448                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16449
16450         { &hf_smb_server_cap_large_writex,
16451                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16452                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16453
16454         { &hf_smb_server_cap_unix,
16455                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16456                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16457
16458         { &hf_smb_server_cap_reserved,
16459                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16460                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16461
16462         { &hf_smb_server_cap_bulk_transfer,
16463                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16464                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16465
16466         { &hf_smb_server_cap_compressed_data,
16467                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16468                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16469
16470         { &hf_smb_server_cap_extended_security,
16471                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16472                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16473
16474         { &hf_smb_system_time,
16475                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16476                 NULL, 0, "System Time", HFILL }},
16477
16478         { &hf_smb_unknown,
16479                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16480                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16481
16482         { &hf_smb_dir_name,
16483                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16484                 NULL, 0, "SMB Directory Name", HFILL }},
16485
16486         { &hf_smb_echo_count,
16487                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16488                 NULL, 0, "Number of times to echo data back", HFILL }},
16489
16490         { &hf_smb_echo_data,
16491                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16492                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16493
16494         { &hf_smb_echo_seq_num,
16495                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16496                 NULL, 0, "Sequence number for this echo response", HFILL }},
16497
16498         { &hf_smb_max_buf_size,
16499                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16500                 NULL, 0, "Max client buffer size", HFILL }},
16501
16502         { &hf_smb_path,
16503                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16504                 NULL, 0, "Path. Server name and share name", HFILL }},
16505
16506         { &hf_smb_service,
16507                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16508                 NULL, 0, "Service name", HFILL }},
16509
16510         { &hf_smb_password,
16511                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16512                 NULL, 0, "Password", HFILL }},
16513
16514         { &hf_smb_ansi_password,
16515                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16516                 NULL, 0, "ANSI Password", HFILL }},
16517
16518         { &hf_smb_unicode_password,
16519                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16520                 NULL, 0, "Unicode Password", HFILL }},
16521
16522         { &hf_smb_move_flags_file,
16523                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16524                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16525
16526         { &hf_smb_move_flags_dir,
16527                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16528                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16529
16530         { &hf_smb_move_flags_verify,
16531                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16532                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16533
16534         { &hf_smb_files_moved,
16535                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16536                 NULL, 0, "Number of files moved", HFILL }},
16537
16538         { &hf_smb_copy_flags_file,
16539                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16540                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16541
16542         { &hf_smb_copy_flags_dir,
16543                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16544                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16545
16546         { &hf_smb_copy_flags_dest_mode,
16547                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16548                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16549
16550         { &hf_smb_copy_flags_source_mode,
16551                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16552                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16553
16554         { &hf_smb_copy_flags_verify,
16555                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16556                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16557
16558         { &hf_smb_copy_flags_tree_copy,
16559                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16560                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16561
16562         { &hf_smb_copy_flags_ea_action,
16563                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16564                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16565
16566         { &hf_smb_count,
16567                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16568                 NULL, 0, "Count number of items/bytes", HFILL }},
16569
16570         { &hf_smb_file_name,
16571                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16572                 NULL, 0, "File Name", HFILL }},
16573
16574         { &hf_smb_open_function_create,
16575                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16576                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16577
16578         { &hf_smb_open_function_open,
16579                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16580                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16581
16582         { &hf_smb_fid,
16583                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16584                 NULL, 0, "FID: File ID", HFILL }},
16585
16586         { &hf_smb_file_attr_read_only_16bit,
16587                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16588                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16589
16590         { &hf_smb_file_attr_read_only_8bit,
16591                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16592                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16593
16594         { &hf_smb_file_attr_hidden_16bit,
16595                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16596                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16597
16598         { &hf_smb_file_attr_hidden_8bit,
16599                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16600                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16601
16602         { &hf_smb_file_attr_system_16bit,
16603                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16604                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16605
16606         { &hf_smb_file_attr_system_8bit,
16607                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16608                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16609
16610         { &hf_smb_file_attr_volume_16bit,
16611                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16612                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16613
16614         { &hf_smb_file_attr_volume_8bit,
16615                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16616                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16617
16618         { &hf_smb_file_attr_directory_16bit,
16619                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16620                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16621
16622         { &hf_smb_file_attr_directory_8bit,
16623                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16624                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16625
16626         { &hf_smb_file_attr_archive_16bit,
16627                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16628                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16629
16630         { &hf_smb_file_attr_archive_8bit,
16631                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16632                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16633
16634         { &hf_smb_file_attr_device,
16635                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16636                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16637
16638         { &hf_smb_file_attr_normal,
16639                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16640                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16641
16642         { &hf_smb_file_attr_temporary,
16643                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16644                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16645
16646         { &hf_smb_file_attr_sparse,
16647                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16648                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16649
16650         { &hf_smb_file_attr_reparse,
16651                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16652                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16653
16654         { &hf_smb_file_attr_compressed,
16655                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16656                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16657
16658         { &hf_smb_file_attr_offline,
16659                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16660                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16661
16662         { &hf_smb_file_attr_not_content_indexed,
16663                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16664                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16665
16666         { &hf_smb_file_attr_encrypted,
16667                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16668                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16669
16670         { &hf_smb_file_size,
16671                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16672                 NULL, 0, "File Size", HFILL }},
16673
16674         { &hf_smb_search_attribute_read_only,
16675                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16676                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16677
16678         { &hf_smb_search_attribute_hidden,
16679                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16680                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16681
16682         { &hf_smb_search_attribute_system,
16683                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16684                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16685
16686         { &hf_smb_search_attribute_volume,
16687                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16688                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16689
16690         { &hf_smb_search_attribute_directory,
16691                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16692                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16693
16694         { &hf_smb_search_attribute_archive,
16695                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16696                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16697
16698         { &hf_smb_access_mode,
16699                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16700                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16701
16702         { &hf_smb_access_sharing,
16703                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16704                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16705
16706         { &hf_smb_access_locality,
16707                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16708                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16709
16710         { &hf_smb_access_caching,
16711                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16712                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16713
16714         { &hf_smb_access_writetru,
16715                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16716                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16717
16718         { &hf_smb_create_time,
16719                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16720                 NULL, 0, "Creation Time", HFILL }},
16721
16722         { &hf_smb_modify_time,
16723                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
16724                   NULL, 0, "Modification Time", HFILL }},
16725
16726         { &hf_smb_backup_time,
16727                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
16728                   NULL, 0, "Backup time", HFILL}},
16729
16730         { &hf_smb_mac_alloc_block_count,
16731                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
16732                   NULL, 0, "Allocation Block Count", HFILL}},
16733
16734         { &hf_smb_mac_alloc_block_size,
16735                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
16736                   NULL, 0, "Allocation Block Size", HFILL}},
16737
16738         { &hf_smb_mac_free_block_count,
16739                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
16740                   NULL, 0, "Free Block Count", HFILL}},
16741
16742         { &hf_smb_mac_root_file_count,
16743                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
16744                 NULL, 0, "Root File Count", HFILL}},
16745
16746         { &hf_smb_mac_root_dir_count,
16747           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
16748             NULL, 0, "Root Directory Count", HFILL}},
16749
16750         { &hf_smb_mac_file_count,
16751           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
16752             NULL, 0, "File Count", HFILL}},
16753
16754         { &hf_smb_mac_dir_count,
16755           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
16756             NULL, 0, "Directory Count", HFILL}},
16757
16758         { &hf_smb_mac_support_flags,
16759           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
16760             NULL, 0, "Mac Support Flags", HFILL}},
16761
16762         { &hf_smb_mac_sup_access_ctrl,
16763           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
16764             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
16765
16766         { &hf_smb_mac_sup_getset_comments,
16767           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
16768             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
16769
16770         { &hf_smb_mac_sup_desktopdb_calls,
16771           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
16772             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
16773
16774         { &hf_smb_mac_sup_unique_ids,
16775           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
16776             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
16777
16778         { &hf_smb_mac_sup_streams,
16779           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
16780             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
16781
16782         { &hf_smb_create_dos_date,
16783                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16784                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16785
16786         { &hf_smb_create_dos_time,
16787                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16788                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16789
16790         { &hf_smb_last_write_time,
16791                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16792                 NULL, 0, "Time this file was last written to", HFILL }},
16793
16794         { &hf_smb_last_write_dos_date,
16795                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16796                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16797
16798         { &hf_smb_last_write_dos_time,
16799                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16800                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16801
16802         { &hf_smb_old_file_name,
16803                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
16804                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16805
16806         { &hf_smb_offset,
16807                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16808                 NULL, 0, "Offset in file", HFILL }},
16809
16810         { &hf_smb_remaining,
16811                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16812                 NULL, 0, "Remaining number of bytes", HFILL }},
16813
16814         { &hf_smb_padding,
16815                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16816                 NULL, 0, "Padding or unknown data", HFILL }},
16817
16818         { &hf_smb_file_data,
16819                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16820                 NULL, 0, "Data read/written to the file", HFILL }},
16821
16822         { &hf_smb_mac_fndrinfo,
16823                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
16824                   NULL, 0, "Finder Info", HFILL}},
16825
16826         { &hf_smb_total_data_len,
16827                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16828                 NULL, 0, "Total length of data", HFILL }},
16829
16830         { &hf_smb_data_len,
16831                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16832                 NULL, 0, "Length of data", HFILL }},
16833
16834         { &hf_smb_seek_mode,
16835                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16836                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16837
16838         { &hf_smb_access_time,
16839                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16840                 NULL, 0, "Last Access Time", HFILL }},
16841
16842         { &hf_smb_access_dos_date,
16843                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16844                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16845
16846         { &hf_smb_access_dos_time,
16847                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16848                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16849
16850         { &hf_smb_data_size,
16851                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16852                 NULL, 0, "Data Size", HFILL }},
16853
16854         { &hf_smb_alloc_size,
16855                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16856                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16857
16858         { &hf_smb_max_count,
16859                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16860                 NULL, 0, "Maximum Count", HFILL }},
16861
16862         { &hf_smb_min_count,
16863                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16864                 NULL, 0, "Minimum Count", HFILL }},
16865
16866         { &hf_smb_timeout,
16867                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16868                 NULL, 0, "Timeout in miliseconds", HFILL }},
16869
16870         { &hf_smb_high_offset,
16871                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16872                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16873
16874         { &hf_smb_units,
16875                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16876                 NULL, 0, "Total number of units at server", HFILL }},
16877
16878         { &hf_smb_bpu,
16879                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16880                 NULL, 0, "Blocks per unit at server", HFILL }},
16881
16882         { &hf_smb_blocksize,
16883                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16884                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16885
16886         { &hf_smb_freeunits,
16887                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16888                 NULL, 0, "Number of free units at server", HFILL }},
16889
16890         { &hf_smb_data_offset,
16891                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16892                 NULL, 0, "Data Offset", HFILL }},
16893
16894         { &hf_smb_dcm,
16895                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16896                 NULL, 0, "Data Compaction Mode", HFILL }},
16897
16898         { &hf_smb_request_mask,
16899                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
16900                 NULL, 0, "Connectionless mode mask", HFILL }},
16901
16902         { &hf_smb_response_mask,
16903                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
16904                 NULL, 0, "Connectionless mode mask", HFILL }},
16905
16906         { &hf_smb_search_id,
16907                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
16908                 NULL, 0, "Search ID, handle for find operations", HFILL }},
16909
16910         { &hf_smb_write_mode_write_through,
16911                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
16912                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
16913
16914         { &hf_smb_write_mode_return_remaining,
16915                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
16916                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
16917
16918         { &hf_smb_write_mode_raw,
16919                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
16920                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
16921
16922         { &hf_smb_write_mode_message_start,
16923                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
16924                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
16925
16926         { &hf_smb_write_mode_connectionless,
16927                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
16928                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
16929
16930         { &hf_smb_resume_key_len,
16931                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
16932                 NULL, 0, "Resume Key length", HFILL }},
16933
16934         { &hf_smb_resume_find_id,
16935                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
16936                 NULL, 0, "Handle for Find operation", HFILL }},
16937
16938         { &hf_smb_resume_server_cookie,
16939                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
16940                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
16941
16942         { &hf_smb_resume_client_cookie,
16943                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
16944                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
16945
16946         { &hf_smb_andxoffset,
16947                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
16948                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
16949
16950         { &hf_smb_lock_type_large,
16951                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
16952                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
16953
16954         { &hf_smb_lock_type_cancel,
16955                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
16956                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
16957
16958         { &hf_smb_lock_type_change,
16959                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
16960                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
16961
16962         { &hf_smb_lock_type_oplock,
16963                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
16964                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
16965
16966         { &hf_smb_lock_type_shared,
16967                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
16968                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
16969
16970         { &hf_smb_locking_ol,
16971                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
16972                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
16973
16974         { &hf_smb_number_of_locks,
16975                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
16976                 NULL, 0, "Number of lock requests in this request", HFILL }},
16977
16978         { &hf_smb_number_of_unlocks,
16979                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
16980                 NULL, 0, "Number of unlock requests in this request", HFILL }},
16981
16982         { &hf_smb_lock_long_length,
16983                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
16984                 NULL, 0, "Length of lock/unlock region", HFILL }},
16985
16986         { &hf_smb_lock_long_offset,
16987                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
16988                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
16989
16990         { &hf_smb_file_type,
16991                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
16992                 VALS(filetype_vals), 0, "Type of file", HFILL }},
16993
16994         { &hf_smb_ipc_state_nonblocking,
16995                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
16996                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
16997
16998         { &hf_smb_ipc_state_endpoint,
16999                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17000                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17001
17002         { &hf_smb_ipc_state_pipe_type,
17003                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17004                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17005
17006         { &hf_smb_ipc_state_read_mode,
17007                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17008                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17009
17010         { &hf_smb_ipc_state_icount,
17011                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17012                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17013
17014         { &hf_smb_server_fid,
17015                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17016                 NULL, 0, "Server unique File ID", HFILL }},
17017
17018         { &hf_smb_open_flags_add_info,
17019                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17020                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17021
17022         { &hf_smb_open_flags_ex_oplock,
17023                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17024                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17025
17026         { &hf_smb_open_flags_batch_oplock,
17027                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17028                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17029
17030         { &hf_smb_open_flags_ealen,
17031                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17032                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17033
17034         { &hf_smb_open_action_open,
17035                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17036                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17037
17038         { &hf_smb_open_action_lock,
17039                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17040                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17041
17042         { &hf_smb_vc_num,
17043                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17044                 NULL, 0, "VC Number", HFILL }},
17045
17046         { &hf_smb_password_len,
17047                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17048                 NULL, 0, "Length of password", HFILL }},
17049
17050         { &hf_smb_ansi_password_len,
17051                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17052                 NULL, 0, "Length of ANSI password", HFILL }},
17053
17054         { &hf_smb_unicode_password_len,
17055                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17056                 NULL, 0, "Length of Unicode password", HFILL }},
17057
17058         { &hf_smb_account,
17059                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17060                 NULL, 0, "Account, username", HFILL }},
17061
17062         { &hf_smb_os,
17063                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17064                 NULL, 0, "Which OS we are running", HFILL }},
17065
17066         { &hf_smb_lanman,
17067                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17068                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17069
17070         { &hf_smb_setup_action_guest,
17071                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17072                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17073
17074         { &hf_smb_fs,
17075                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17076                 NULL, 0, "Native File System", HFILL }},
17077
17078         { &hf_smb_connect_flags_dtid,
17079                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17080                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17081
17082         { &hf_smb_connect_support_search,
17083                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17084                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17085
17086         { &hf_smb_connect_support_in_dfs,
17087                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17088                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17089
17090         { &hf_smb_max_setup_count,
17091                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17092                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17093
17094         { &hf_smb_total_param_count,
17095                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17096                 NULL, 0, "Total number of parameter bytes", HFILL }},
17097
17098         { &hf_smb_total_data_count,
17099                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17100                 NULL, 0, "Total number of data bytes", HFILL }},
17101
17102         { &hf_smb_max_param_count,
17103                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17104                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17105
17106         { &hf_smb_max_data_count,
17107                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17108                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17109
17110         { &hf_smb_param_disp16,
17111                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17112                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17113
17114         { &hf_smb_param_count16,
17115                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17116                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17117
17118         { &hf_smb_param_offset16,
17119                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17120                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17121
17122         { &hf_smb_param_disp32,
17123                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17124                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17125
17126         { &hf_smb_param_count32,
17127                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17128                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17129
17130         { &hf_smb_param_offset32,
17131                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17132                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17133
17134         { &hf_smb_data_count16,
17135                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17136                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17137
17138         { &hf_smb_data_disp16,
17139                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17140                 NULL, 0, "Data Displacement", HFILL }},
17141
17142         { &hf_smb_data_offset16,
17143                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17144                 NULL, 0, "Data Offset", HFILL }},
17145
17146         { &hf_smb_data_count32,
17147                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17148                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17149
17150         { &hf_smb_data_disp32,
17151                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17152                 NULL, 0, "Data Displacement", HFILL }},
17153
17154         { &hf_smb_data_offset32,
17155                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17156                 NULL, 0, "Data Offset", HFILL }},
17157
17158         { &hf_smb_setup_count,
17159                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17160                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17161
17162         { &hf_smb_nt_trans_subcmd,
17163                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17164                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17165
17166         { &hf_smb_nt_ioctl_function_code,
17167                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17168                 NULL, 0, "NT IOCTL function code", HFILL }},
17169
17170         { &hf_smb_nt_ioctl_isfsctl,
17171                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17172                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17173
17174         { &hf_smb_nt_ioctl_flags_root_handle,
17175                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17176                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17177
17178         { &hf_smb_nt_ioctl_data,
17179                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17180                 NULL, 0, "Data for the IOCTL call", HFILL }},
17181
17182         { &hf_smb_nt_notify_action,
17183                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17184                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17185
17186         { &hf_smb_nt_notify_watch_tree,
17187                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17188                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17189
17190         { &hf_smb_nt_notify_stream_write,
17191                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17192                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17193
17194         { &hf_smb_nt_notify_stream_size,
17195                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17196                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17197
17198         { &hf_smb_nt_notify_stream_name,
17199                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17200                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17201
17202         { &hf_smb_nt_notify_security,
17203                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17204                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17205
17206         { &hf_smb_nt_notify_ea,
17207                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17208                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17209
17210         { &hf_smb_nt_notify_creation,
17211                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17212                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17213
17214         { &hf_smb_nt_notify_last_access,
17215                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17216                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17217
17218         { &hf_smb_nt_notify_last_write,
17219                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17220                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17221
17222         { &hf_smb_nt_notify_size,
17223                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17224                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17225
17226         { &hf_smb_nt_notify_attributes,
17227                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17228                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17229
17230         { &hf_smb_nt_notify_dir_name,
17231                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17232                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17233
17234         { &hf_smb_nt_notify_file_name,
17235                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17236                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17237
17238         { &hf_smb_root_dir_fid,
17239                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17240                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17241
17242         { &hf_smb_alloc_size64,
17243                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17244                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17245
17246         { &hf_smb_nt_create_disposition,
17247                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17248                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17249
17250         { &hf_smb_sd_length,
17251                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17252                 NULL, 0, "Total length of security descriptor", HFILL }},
17253
17254         { &hf_smb_ea_length,
17255                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
17256                 NULL, 0, "Total EA length for opened file", HFILL }},
17257
17258         { &hf_smb_file_name_len,
17259                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17260                 NULL, 0, "Length of File Name", HFILL }},
17261
17262         { &hf_smb_nt_impersonation_level,
17263                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17264                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17265
17266         { &hf_smb_nt_security_flags_context_tracking,
17267                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17268                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17269
17270         { &hf_smb_nt_security_flags_effective_only,
17271                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17272                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17273
17274         { &hf_smb_nt_access_mask_generic_read,
17275                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17276                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17277
17278         { &hf_smb_nt_access_mask_generic_write,
17279                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17280                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17281
17282         { &hf_smb_nt_access_mask_generic_execute,
17283                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17284                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17285
17286         { &hf_smb_nt_access_mask_generic_all,
17287                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17288                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17289
17290         { &hf_smb_nt_access_mask_maximum_allowed,
17291                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17292                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17293
17294         { &hf_smb_nt_access_mask_system_security,
17295                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17296                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17297
17298         { &hf_smb_nt_access_mask_synchronize,
17299                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17300                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17301
17302         { &hf_smb_nt_access_mask_write_owner,
17303                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17304                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17305
17306         { &hf_smb_nt_access_mask_write_dac,
17307                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17308                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17309
17310         { &hf_smb_nt_access_mask_read_control,
17311                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17312                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17313
17314         { &hf_smb_nt_access_mask_delete,
17315                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17316                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17317
17318         { &hf_smb_nt_access_mask_write_attributes,
17319                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17320                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17321
17322         { &hf_smb_nt_access_mask_read_attributes,
17323                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17324                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17325
17326         { &hf_smb_nt_access_mask_delete_child,
17327                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17328                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17329
17330         /*
17331          * "Execute" for files, "traverse" for directories.
17332          */
17333         { &hf_smb_nt_access_mask_execute,
17334                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17335                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17336
17337         { &hf_smb_nt_access_mask_write_ea,
17338                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17339                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17340
17341         { &hf_smb_nt_access_mask_read_ea,
17342                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17343                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17344
17345         /*
17346          * "Append data" for files, "add subdirectory" for directories,
17347          * "create pipe instance" for named pipes.
17348          */
17349         { &hf_smb_nt_access_mask_append,
17350                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17351                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17352
17353         /*
17354          * "Write data" for files and pipes, "add file" for directory.
17355          */
17356         { &hf_smb_nt_access_mask_write,
17357                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17358                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17359
17360         /*
17361          * "Read data" for files and pipes, "list directory" for directory.
17362          */
17363         { &hf_smb_nt_access_mask_read,
17364                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17365                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17366
17367         { &hf_smb_nt_create_bits_oplock,
17368                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17369                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17370
17371         { &hf_smb_nt_create_bits_boplock,
17372                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17373                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17374
17375         { &hf_smb_nt_create_bits_dir,
17376                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17377                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17378
17379         { &hf_smb_nt_create_bits_ext_resp,
17380           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
17381             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
17382
17383         { &hf_smb_nt_create_options_directory_file,
17384                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17385                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17386
17387         { &hf_smb_nt_create_options_write_through,
17388                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17389                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17390
17391         { &hf_smb_nt_create_options_sequential_only,
17392                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17393                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17394
17395         { &hf_smb_nt_create_options_sync_io_alert,
17396                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17397                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17398
17399         { &hf_smb_nt_create_options_sync_io_nonalert,
17400                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17401                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17402
17403         { &hf_smb_nt_create_options_non_directory_file,
17404                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17405                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17406
17407         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
17408            and "NtOpenFile()"; is that sent over the wire?  Network
17409            Monitor thinks so, but its author may just have grabbed
17410            the flag bits from a system header file. */
17411
17412         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
17413            and "NtOpenFile()"; is that sent over the wire?  NetMon
17414            thinks so, but see previous comment. */
17415
17416         { &hf_smb_nt_create_options_no_ea_knowledge,
17417                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17418                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17419
17420         { &hf_smb_nt_create_options_eight_dot_three_only,
17421                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17422                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17423
17424         { &hf_smb_nt_create_options_random_access,
17425                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17426                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17427
17428         { &hf_smb_nt_create_options_delete_on_close,
17429                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17430                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17431
17432         /* 0x00002000 is "open by FID", or something such as that (which
17433            I suspect is like "open by inumber" on UNIX), at least in
17434            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
17435            wire?  NetMon thinks so, but see previous comment. */
17436
17437         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
17438            and "NtOpenFile()"; is that sent over the wire?  NetMon
17439            thinks so, but see previous comment. */
17440
17441         { &hf_smb_nt_share_access_read,
17442                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17443                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
17444
17445         { &hf_smb_nt_share_access_write,
17446                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17447                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
17448
17449         { &hf_smb_nt_share_access_delete,
17450                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17451                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
17452
17453         { &hf_smb_file_eattr_read_only,
17454                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17455                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17456
17457         { &hf_smb_file_eattr_hidden,
17458                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17459                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17460
17461         { &hf_smb_file_eattr_system,
17462                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17463                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17464
17465         { &hf_smb_file_eattr_volume,
17466                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
17467                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17468
17469         { &hf_smb_file_eattr_directory,
17470                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
17471                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17472
17473         { &hf_smb_file_eattr_archive,
17474                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17475                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17476
17477         { &hf_smb_file_eattr_device,
17478                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17479                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17480
17481         { &hf_smb_file_eattr_normal,
17482                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17483                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17484
17485         { &hf_smb_file_eattr_temporary,
17486                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17487                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17488
17489         { &hf_smb_file_eattr_sparse,
17490                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17491                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17492
17493         { &hf_smb_file_eattr_reparse,
17494                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17495                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17496
17497         { &hf_smb_file_eattr_compressed,
17498                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17499                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17500
17501         { &hf_smb_file_eattr_offline,
17502                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17503                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17504
17505         { &hf_smb_file_eattr_not_content_indexed,
17506                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17507                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17508
17509         { &hf_smb_file_eattr_encrypted,
17510                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17511                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17512
17513         { &hf_smb_sec_desc_len,
17514                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17515                 NULL, 0, "Security Descriptor Length", HFILL }},
17516
17517         { &hf_smb_nt_qsd_owner,
17518                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17519                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17520
17521         { &hf_smb_nt_qsd_group,
17522                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17523                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17524
17525         { &hf_smb_nt_qsd_dacl,
17526                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17527                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17528
17529         { &hf_smb_nt_qsd_sacl,
17530                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17531                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17532
17533         { &hf_smb_extended_attributes,
17534                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17535                 NULL, 0, "Extended Attributes", HFILL }},
17536
17537         { &hf_smb_oplock_level,
17538                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17539                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17540
17541         { &hf_smb_create_action,
17542                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17543                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
17544
17545         { &hf_smb_file_id,
17546                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17547                 NULL, 0, "Server unique file ID", HFILL }},
17548
17549         { &hf_smb_ea_error_offset,
17550                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
17551                 NULL, 0, "Offset into EA list if EA error", HFILL }},
17552
17553         { &hf_smb_end_of_file,
17554                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
17555                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
17556
17557         { &hf_smb_device_type,
17558                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
17559                 VALS(device_type_vals), 0, "Type of device", HFILL }},
17560
17561         { &hf_smb_is_directory,
17562                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
17563                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
17564
17565         { &hf_smb_next_entry_offset,
17566                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
17567                 NULL, 0, "Offset to next entry", HFILL }},
17568
17569         { &hf_smb_change_time,
17570                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
17571                 NULL, 0, "Last Change Time", HFILL }},
17572
17573         { &hf_smb_setup_len,
17574                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
17575                 NULL, 0, "Length of printer setup data", HFILL }},
17576
17577         { &hf_smb_print_mode,
17578                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
17579                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
17580
17581         { &hf_smb_print_identifier,
17582                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
17583                 NULL, 0, "Identifier string for this print job", HFILL }},
17584
17585         { &hf_smb_restart_index,
17586                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
17587                 NULL, 0, "Index of entry after last returned", HFILL }},
17588
17589         { &hf_smb_print_queue_date,
17590                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
17591                 NULL, 0, "Date when this entry was queued", HFILL }},
17592
17593         { &hf_smb_print_queue_dos_date,
17594                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
17595                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
17596
17597         { &hf_smb_print_queue_dos_time,
17598                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17599                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17600
17601         { &hf_smb_print_status,
17602                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17603                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17604
17605         { &hf_smb_print_spool_file_number,
17606                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17607                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17608
17609         { &hf_smb_print_spool_file_size,
17610                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17611                 NULL, 0, "Number of bytes in spool file", HFILL }},
17612
17613         { &hf_smb_print_spool_file_name,
17614                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17615                 NULL, 0, "Name of client that submitted this job", HFILL }},
17616
17617         { &hf_smb_start_index,
17618                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17619                 NULL, 0, "First queue entry to return", HFILL }},
17620
17621         { &hf_smb_originator_name,
17622                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17623                 NULL, 0, "Name of sender of message", HFILL }},
17624
17625         { &hf_smb_destination_name,
17626                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17627                 NULL, 0, "Name of recipient of message", HFILL }},
17628
17629         { &hf_smb_message_len,
17630                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17631                 NULL, 0, "Length of message", HFILL }},
17632
17633         { &hf_smb_message,
17634                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17635                 NULL, 0, "Message text", HFILL }},
17636
17637         { &hf_smb_mgid,
17638                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17639                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17640
17641         { &hf_smb_forwarded_name,
17642                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17643                 NULL, 0, "Recipient name being forwarded", HFILL }},
17644
17645         { &hf_smb_machine_name,
17646                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17647                 NULL, 0, "Name of target machine", HFILL }},
17648
17649         { &hf_smb_cancel_to,
17650                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
17651                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17652
17653         { &hf_smb_trans2_subcmd,
17654                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17655                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17656
17657         { &hf_smb_trans_name,
17658                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17659                 NULL, 0, "Name of transaction", HFILL }},
17660
17661         { &hf_smb_transaction_flags_dtid,
17662                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17663                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17664
17665         { &hf_smb_transaction_flags_owt,
17666                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17667                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17668
17669         { &hf_smb_search_count,
17670                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17671                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17672
17673         { &hf_smb_search_pattern,
17674                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17675                 NULL, 0, "Search Pattern", HFILL }},
17676
17677         { &hf_smb_ff2_backup,
17678                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17679                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17680
17681         { &hf_smb_ff2_continue,
17682                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17683                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17684
17685         { &hf_smb_ff2_resume,
17686                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17687                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17688
17689         { &hf_smb_ff2_close_eos,
17690                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17691                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17692
17693         { &hf_smb_ff2_close,
17694                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17695                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17696
17697         { &hf_smb_ff2_information_level,
17698                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17699                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17700
17701         { &hf_smb_qpi_loi,
17702                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
17703                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
17704
17705 #if 0
17706         { &hf_smb_sfi_writetru,
17707                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17708                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17709
17710         { &hf_smb_sfi_caching,
17711                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17712                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17713 #endif
17714
17715         { &hf_smb_storage_type,
17716                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17717                 NULL, 0, "Type of storage", HFILL }},
17718
17719         { &hf_smb_resume,
17720                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17721                 NULL, 0, "Resume Key", HFILL }},
17722
17723         { &hf_smb_max_referral_level,
17724                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17725                 NULL, 0, "Latest referral version number understood", HFILL }},
17726
17727         { &hf_smb_qfsi_information_level,
17728                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
17729                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17730
17731         { &hf_smb_nt_rename_level,
17732                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17733                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17734
17735         { &hf_smb_cluster_count,
17736                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17737                 NULL, 0, "Number of clusters", HFILL }},
17738
17739         { &hf_smb_ea_size,
17740                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
17741                 NULL, 0, "Size of file's EA information", HFILL }},
17742
17743         { &hf_smb_list_length,
17744                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
17745                 NULL, 0, "Length of the remaining data", HFILL }},
17746
17747         { &hf_smb_number_of_links,
17748                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17749                 NULL, 0, "Number of hard links to the file", HFILL }},
17750
17751         { &hf_smb_delete_pending,
17752                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17753                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17754
17755         { &hf_smb_index_number,
17756                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17757                 NULL, 0, "File system unique identifier", HFILL }},
17758
17759         { &hf_smb_current_offset,
17760                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17761                 NULL, 0, "Current offset in the file", HFILL }},
17762
17763         { &hf_smb_t2_alignment,
17764                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17765                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17766
17767         { &hf_smb_t2_stream_name_length,
17768                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17769                 NULL, 0, "Length of stream name", HFILL }},
17770
17771         { &hf_smb_t2_stream_size,
17772                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17773                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17774
17775         { &hf_smb_t2_stream_name,
17776                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17777                 NULL, 0, "Name of the stream", HFILL }},
17778
17779         { &hf_smb_t2_compressed_file_size,
17780                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17781                 NULL, 0, "Size of the compressed file", HFILL }},
17782
17783         { &hf_smb_t2_compressed_format,
17784                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17785                 NULL, 0, "Compression algorithm used", HFILL }},
17786
17787         { &hf_smb_t2_compressed_unit_shift,
17788                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17789                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17790
17791         { &hf_smb_t2_compressed_chunk_shift,
17792                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17793                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17794
17795         { &hf_smb_t2_compressed_cluster_shift,
17796                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17797                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17798
17799         { &hf_smb_dfs_path_consumed,
17800                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17801                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17802
17803         { &hf_smb_dfs_num_referrals,
17804                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17805                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17806
17807         { &hf_smb_get_dfs_server_hold_storage,
17808                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17809                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17810
17811         { &hf_smb_get_dfs_fielding,
17812                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17813                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17814
17815         { &hf_smb_dfs_referral_version,
17816                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17817                 NULL, 0, "Version of referral element", HFILL }},
17818
17819         { &hf_smb_dfs_referral_size,
17820                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17821                 NULL, 0, "Size of referral element", HFILL }},
17822
17823         { &hf_smb_dfs_referral_server_type,
17824                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17825                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17826
17827         { &hf_smb_dfs_referral_flags_strip,
17828                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17829                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17830
17831         { &hf_smb_dfs_referral_node_offset,
17832                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17833                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17834
17835         { &hf_smb_dfs_referral_node,
17836                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17837                 NULL, 0, "Name of entity to visit next", HFILL }},
17838
17839         { &hf_smb_dfs_referral_proximity,
17840                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17841                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17842
17843         { &hf_smb_dfs_referral_ttl,
17844                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17845                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17846
17847         { &hf_smb_dfs_referral_path_offset,
17848                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17849                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17850
17851         { &hf_smb_dfs_referral_path,
17852                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
17853                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
17854
17855         { &hf_smb_dfs_referral_alt_path_offset,
17856                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
17857                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
17858
17859         { &hf_smb_dfs_referral_alt_path,
17860                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
17861                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
17862
17863         { &hf_smb_end_of_search,
17864                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
17865                 NULL, 0, "Was last entry returned?", HFILL }},
17866
17867         { &hf_smb_last_name_offset,
17868                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
17869                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
17870
17871         { &hf_smb_fn_information_level,
17872                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
17873                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
17874
17875         { &hf_smb_monitor_handle,
17876                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
17877                 NULL, 0, "Handle for Find Notify operations", HFILL }},
17878
17879         { &hf_smb_change_count,
17880                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
17881                 NULL, 0, "Number of changes to wait for", HFILL }},
17882
17883         { &hf_smb_file_index,
17884                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
17885                 NULL, 0, "File index", HFILL }},
17886
17887         { &hf_smb_short_file_name,
17888                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
17889                 NULL, 0, "Short (8.3) File Name", HFILL }},
17890
17891         { &hf_smb_short_file_name_len,
17892                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
17893                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
17894
17895         { &hf_smb_fs_id,
17896                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
17897                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
17898
17899         { &hf_smb_sector_unit,
17900                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
17901                 NULL, 0, "Sectors per allocation unit", HFILL }},
17902
17903         { &hf_smb_fs_units,
17904                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
17905                 NULL, 0, "Total number of units on this filesystem", HFILL }},
17906
17907         { &hf_smb_fs_sector,
17908                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
17909                 NULL, 0, "Bytes per sector", HFILL }},
17910
17911         { &hf_smb_avail_units,
17912                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
17913                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
17914
17915         { &hf_smb_volume_serial_num,
17916                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
17917                 NULL, 0, "Volume serial number", HFILL }},
17918
17919         { &hf_smb_volume_label_len,
17920                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
17921                 NULL, 0, "Length of volume label", HFILL }},
17922
17923         { &hf_smb_volume_label,
17924                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
17925                 NULL, 0, "Volume label", HFILL }},
17926
17927         { &hf_smb_free_alloc_units64,
17928                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
17929                 NULL, 0, "Number of free allocation units", HFILL }},
17930
17931         { &hf_smb_caller_free_alloc_units64,
17932                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
17933                 NULL, 0, "Number of caller free allocation units", HFILL }},
17934
17935         { &hf_smb_actual_free_alloc_units64,
17936                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
17937                 NULL, 0, "Number of actual free allocation units", HFILL }},
17938
17939         { &hf_smb_soft_quota_limit,
17940                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
17941                 NULL, 0, "Soft Quota treshold", HFILL }},
17942
17943         { &hf_smb_hard_quota_limit,
17944                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
17945                 NULL, 0, "Hard Quota limit", HFILL }},
17946
17947         { &hf_smb_user_quota_used,
17948                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
17949                 NULL, 0, "How much Quota is used by this user", HFILL }},
17950
17951         { &hf_smb_max_name_len,
17952                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
17953                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
17954
17955         { &hf_smb_fs_name_len,
17956                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
17957                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
17958
17959         { &hf_smb_fs_name,
17960                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
17961                 NULL, 0, "Name of filesystem", HFILL }},
17962
17963         { &hf_smb_device_char_removable,
17964                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
17965                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
17966
17967         { &hf_smb_device_char_read_only,
17968                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
17969                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
17970
17971         { &hf_smb_device_char_floppy,
17972                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
17973                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
17974
17975         { &hf_smb_device_char_write_once,
17976                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
17977                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
17978
17979         { &hf_smb_device_char_remote,
17980                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
17981                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
17982
17983         { &hf_smb_device_char_mounted,
17984                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
17985                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
17986
17987         { &hf_smb_device_char_virtual,
17988                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
17989                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
17990
17991         { &hf_smb_fs_attr_css,
17992                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
17993                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
17994
17995         { &hf_smb_fs_attr_cpn,
17996                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
17997                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
17998
17999         { &hf_smb_fs_attr_pacls,
18000                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18001                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18002
18003         { &hf_smb_fs_attr_fc,
18004                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18005                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18006
18007         { &hf_smb_fs_attr_vq,
18008                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18009                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18010
18011         { &hf_smb_fs_attr_dim,
18012                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18013                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18014
18015         { &hf_smb_fs_attr_vic,
18016                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18017                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18018
18019         { &hf_smb_sec_desc_revision,
18020                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18021                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18022
18023         { &hf_smb_sid,
18024                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18025                 NULL, 0, "SID: Security Identifier", HFILL }},
18026
18027         { &hf_smb_sid_revision,
18028                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18029                 NULL, 0, "Version of SID structure", HFILL }},
18030
18031         { &hf_smb_sid_num_auth,
18032                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18033                 NULL, 0, "Number of authorities for this SID", HFILL }},
18034
18035         { &hf_smb_acl_revision,
18036                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18037                 NULL, 0, "Version of NT ACL structure", HFILL }},
18038
18039         { &hf_smb_acl_size,
18040                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18041                 NULL, 0, "Size of NT ACL structure", HFILL }},
18042
18043         { &hf_smb_acl_num_aces,
18044                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18045                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18046
18047         { &hf_smb_user_quota_offset,
18048                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18049                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18050
18051         { &hf_smb_ace_type,
18052                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18053                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18054
18055         { &hf_smb_pipe_write_len,
18056                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18057                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18058
18059         { &hf_smb_ace_size,
18060                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18061                 NULL, 0, "Size of this ACE", HFILL }},
18062
18063         { &hf_smb_ace_flags_object_inherit,
18064                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18065                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18066
18067         { &hf_smb_ace_flags_container_inherit,
18068                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18069                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18070
18071         { &hf_smb_ace_flags_non_propagate_inherit,
18072                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18073                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18074
18075         { &hf_smb_ace_flags_inherit_only,
18076                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18077                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18078
18079         { &hf_smb_ace_flags_inherited_ace,
18080                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18081                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18082
18083         { &hf_smb_ace_flags_successful_access,
18084                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18085                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18086
18087         { &hf_smb_ace_flags_failed_access,
18088                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18089                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18090
18091         { &hf_smb_sec_desc_type_owner_defaulted,
18092                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18093                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18094
18095         { &hf_smb_sec_desc_type_group_defaulted,
18096                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18097                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18098
18099         { &hf_smb_sec_desc_type_dacl_present,
18100                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18101                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18102
18103         { &hf_smb_sec_desc_type_dacl_defaulted,
18104                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18105                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18106
18107         { &hf_smb_sec_desc_type_sacl_present,
18108                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18109                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18110
18111         { &hf_smb_sec_desc_type_sacl_defaulted,
18112                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18113                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18114
18115         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18116                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18117                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18118
18119         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18120                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18121                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18122
18123         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18124                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18125                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18126
18127         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18128                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18129                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18130
18131         { &hf_smb_sec_desc_type_dacl_protected,
18132                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18133                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18134
18135         { &hf_smb_sec_desc_type_sacl_protected,
18136                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18137                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18138
18139         { &hf_smb_sec_desc_type_self_relative,
18140                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18141                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18142
18143         { &hf_smb_quota_flags_deny_disk,
18144                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18145                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18146
18147         { &hf_smb_quota_flags_log_limit,
18148                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18149                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18150
18151         { &hf_smb_quota_flags_log_warning,
18152                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18153                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18154
18155         { &hf_smb_quota_flags_enabled,
18156                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18157                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18158
18159         { &hf_smb_segment_overlap,
18160                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18161                         "Fragment overlaps with other fragments", HFILL }},
18162
18163         { &hf_smb_segment_overlap_conflict,
18164                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18165                         "Overlapping fragments contained conflicting data", HFILL }},
18166
18167         { &hf_smb_segment_multiple_tails,
18168                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18169                         "Several tails were found when defragmenting the packet", HFILL }},
18170
18171         { &hf_smb_segment_too_long_fragment,
18172                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18173                         "Fragment contained data past end of packet", HFILL }},
18174
18175         { &hf_smb_segment_error,
18176                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18177                         "Defragmentation error due to illegal fragments", HFILL }},
18178
18179         { &hf_smb_segment,
18180                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18181                         "SMB Segment", HFILL }},
18182
18183         { &hf_smb_segments,
18184                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18185                         "SMB Segments", HFILL }},
18186
18187                 /* Access masks */
18188
18189                 { &hf_smb_access_mask,
18190                   { "Access required", "smb.access_mask",
18191                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18192                     HFILL }},
18193                 { &hf_access_generic_read,
18194                   { "Generic read", "nt.access_mask.generic_read",
18195                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18196                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18197
18198                 { &hf_access_generic_write,
18199                   { "Generic write", "nt.access_mask.generic_write",
18200                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18201                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
18202
18203                 { &hf_access_generic_execute,
18204                   { "Generic execute", "nt.access_mask.generic_execute",
18205                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18206                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
18207
18208                 { &hf_access_generic_all,
18209                   { "Generic all", "nt.access_mask.generic_all",
18210                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18211                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
18212
18213                 { &hf_access_maximum_allowed,
18214                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
18215                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18216                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
18217
18218                 { &hf_access_sacl,
18219                   { "Access SACL", "nt.access_mask.access_sacl",
18220                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18221                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
18222
18223                 { &hf_access_standard_read_control,
18224                   { "Read control", "nt.access_mask.read_control",
18225                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18226                     READ_CONTROL_ACCESS, "Read control", HFILL }},
18227
18228                 { &hf_access_standard_delete,
18229                   { "Delete", "nt.access_mask.delete",
18230                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18231                     DELETE_ACCESS, "Delete", HFILL }},
18232
18233                 { &hf_access_standard_synchronise,
18234                   { "Synchronise", "nt.access_mask.synchronise",
18235                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18236                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
18237
18238                 { &hf_access_standard_write_dac,
18239                   { "Write DAC", "nt.access_mask.write_dac",
18240                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18241                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
18242
18243                 { &hf_access_standard_write_owner,
18244                   { "Write owner", "nt.access_mask.write_owner",
18245                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18246                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
18247
18248                 { &hf_access_specific_15,
18249                   { "Specific access, bit 15", "nt.access_mask.specific_15",
18250                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18251                     0x8000, "Specific access, bit 15", HFILL }},
18252
18253                 { &hf_access_specific_14,
18254                   { "Specific access, bit 14", "nt.access_mask.specific_14",
18255                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18256                     0x4000, "Specific access, bit 14", HFILL }},
18257
18258                 { &hf_access_specific_13,
18259                   { "Specific access, bit 13", "nt.access_mask.specific_13",
18260                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18261                     0x2000, "Specific access, bit 13", HFILL }},
18262
18263                 { &hf_access_specific_12,
18264                   { "Specific access, bit 12", "nt.access_mask.specific_12",
18265                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18266                     0x1000, "Specific access, bit 12", HFILL }},
18267
18268                 { &hf_access_specific_11,
18269                   { "Specific access, bit 11", "nt.access_mask.specific_11",
18270                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18271                     0x0800, "Specific access, bit 11", HFILL }},
18272
18273                 { &hf_access_specific_10,
18274                   { "Specific access, bit 10", "nt.access_mask.specific_10",
18275                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18276                     0x0400, "Specific access, bit 10", HFILL }},
18277
18278                 { &hf_access_specific_9,
18279                   { "Specific access, bit 9", "nt.access_mask.specific_9",
18280                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18281                     0x0200, "Specific access, bit 9", HFILL }},
18282
18283                 { &hf_access_specific_8,
18284                   { "Specific access, bit 8", "nt.access_mask.specific_8",
18285                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18286                     0x0100, "Specific access, bit 8", HFILL }},
18287
18288                 { &hf_access_specific_7,
18289                   { "Specific access, bit 7", "nt.access_mask.specific_7",
18290                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18291                     0x0080, "Specific access, bit 7", HFILL }},
18292
18293                 { &hf_access_specific_6,
18294                   { "Specific access, bit 6", "nt.access_mask.specific_6",
18295                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18296                     0x0040, "Specific access, bit 6", HFILL }},
18297
18298                 { &hf_access_specific_5,
18299                   { "Specific access, bit 5", "nt.access_mask.specific_5",
18300                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18301                     0x0020, "Specific access, bit 5", HFILL }},
18302
18303                 { &hf_access_specific_4,
18304                   { "Specific access, bit 4", "nt.access_mask.specific_4",
18305                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18306                     0x0010, "Specific access, bit 4", HFILL }},
18307
18308                 { &hf_access_specific_3,
18309                   { "Specific access, bit 3", "nt.access_mask.specific_3",
18310                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18311                     0x0008, "Specific access, bit 3", HFILL }},
18312
18313                 { &hf_access_specific_2,
18314                   { "Specific access, bit 2", "nt.access_mask.specific_2",
18315                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18316                     0x0004, "Specific access, bit 2", HFILL }},
18317
18318                 { &hf_access_specific_1,
18319                   { "Specific access, bit 1", "nt.access_mask.specific_1",
18320                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18321                     0x0002, "Specific access, bit 1", HFILL }},
18322
18323                 { &hf_access_specific_0,
18324                   { "Specific access, bit 0", "nt.access_mask.specific_0",
18325                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18326                     0x0001, "Specific access, bit 0", HFILL }}
18327         };
18328
18329         static gint *ett[] = {
18330                 &ett_smb,
18331                 &ett_smb_hdr,
18332                 &ett_smb_command,
18333                 &ett_smb_fileattributes,
18334                 &ett_smb_capabilities,
18335                 &ett_smb_aflags,
18336                 &ett_smb_dialect,
18337                 &ett_smb_dialects,
18338                 &ett_smb_mode,
18339                 &ett_smb_rawmode,
18340                 &ett_smb_flags,
18341                 &ett_smb_flags2,
18342                 &ett_smb_desiredaccess,
18343                 &ett_smb_search,
18344                 &ett_smb_file,
18345                 &ett_smb_openfunction,
18346                 &ett_smb_filetype,
18347                 &ett_smb_openaction,
18348                 &ett_smb_writemode,
18349                 &ett_smb_lock_type,
18350                 &ett_smb_ssetupandxaction,
18351                 &ett_smb_optionsup,
18352                 &ett_smb_time_date,
18353                 &ett_smb_move_copy_flags,
18354                 &ett_smb_file_attributes,
18355                 &ett_smb_search_resume_key,
18356                 &ett_smb_search_dir_info,
18357                 &ett_smb_unlocks,
18358                 &ett_smb_unlock,
18359                 &ett_smb_locks,
18360                 &ett_smb_lock,
18361                 &ett_smb_open_flags,
18362                 &ett_smb_ipc_state,
18363                 &ett_smb_open_action,
18364                 &ett_smb_setup_action,
18365                 &ett_smb_connect_flags,
18366                 &ett_smb_connect_support_bits,
18367                 &ett_smb_nt_access_mask,
18368                 &ett_smb_nt_create_bits,
18369                 &ett_smb_nt_create_options,
18370                 &ett_smb_nt_share_access,
18371                 &ett_smb_nt_security_flags,
18372                 &ett_smb_nt_trans_setup,
18373                 &ett_smb_nt_trans_data,
18374                 &ett_smb_nt_trans_param,
18375                 &ett_smb_nt_notify_completion_filter,
18376                 &ett_smb_nt_ioctl_flags,
18377                 &ett_smb_security_information_mask,
18378                 &ett_smb_print_queue_entry,
18379                 &ett_smb_transaction_flags,
18380                 &ett_smb_transaction_params,
18381                 &ett_smb_find_first2_flags,
18382 #if 0
18383                 &ett_smb_ioflag,
18384 #endif
18385                 &ett_smb_transaction_data,
18386                 &ett_smb_stream_info,
18387                 &ett_smb_dfs_referrals,
18388                 &ett_smb_dfs_referral,
18389                 &ett_smb_dfs_referral_flags,
18390                 &ett_smb_get_dfs_flags,
18391                 &ett_smb_ff2_data,
18392                 &ett_smb_device_characteristics,
18393                 &ett_smb_fs_attributes,
18394                 &ett_smb_segments,
18395                 &ett_smb_segment,
18396                 &ett_smb_sec_desc,
18397                 &ett_smb_sid,
18398                 &ett_smb_acl,
18399                 &ett_smb_ace,
18400                 &ett_smb_ace_flags,
18401                 &ett_smb_sec_desc_type,
18402                 &ett_smb_quotaflags,
18403                 &ett_smb_secblob,
18404                 &ett_smb_mac_support_flags,
18405                 &ett_nt_access_mask,
18406                 &ett_nt_access_mask_generic,
18407                 &ett_nt_access_mask_standard,
18408                 &ett_nt_access_mask_specific,
18409                 &ett_smb_unicode_password
18410         };
18411         module_t *smb_module;
18412
18413         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
18414             "SMB", "smb");
18415         proto_register_subtree_array(ett, array_length(ett));
18416         proto_register_field_array(proto_smb, hf, array_length(hf));
18417
18418         register_smb_common(proto_smb);
18419
18420         register_init_routine(&smb_init_protocol);
18421         smb_module = prefs_register_protocol(proto_smb, NULL);
18422         prefs_register_bool_preference(smb_module, "trans_reassembly",
18423                 "Reassemble SMB Transaction payload",
18424                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
18425                 &smb_trans_reassembly);
18426         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
18427                 "Reassemble DCERPC over SMB",
18428                 "Whether the dissector should reassemble DCERPC over SMB commands",
18429                 &smb_dcerpc_reassembly);
18430         prefs_register_bool_preference(smb_module, "sid_name_snooping",
18431                 "Snoop SID to Name mappings",
18432                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
18433                 &sid_name_snooping);
18434
18435         register_init_routine(smb_trans_reassembly_init);
18436         smb_tap = register_tap("smb");
18437 }
18438
18439 void
18440 proto_reg_handoff_smb(void)
18441 {
18442         dissector_handle_t smb_handle;
18443
18444         gssapi_handle = find_dissector("gssapi");
18445         ntlmssp_handle = find_dissector("ntlmssp");
18446
18447         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
18448         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
18449         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
18450         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
18451         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
18452         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
18453         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
18454             smb_handle);
18455 }