Prep for the 0.9.14 release
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.356 2003/07/10 04:48:59 tpot 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_pid_high = -1;
104 static int hf_smb_sig = -1;
105 static int hf_smb_response_to = -1;
106 static int hf_smb_time = -1;
107 static int hf_smb_response_in = -1;
108 static int hf_smb_continuation_to = -1;
109 static int hf_smb_nt_status = -1;
110 static int hf_smb_error_class = -1;
111 static int hf_smb_error_code = -1;
112 static int hf_smb_reserved = -1;
113 static int hf_smb_flags_lock = -1;
114 static int hf_smb_flags_receive_buffer = -1;
115 static int hf_smb_flags_caseless = -1;
116 static int hf_smb_flags_canon = -1;
117 static int hf_smb_flags_oplock = -1;
118 static int hf_smb_flags_notify = -1;
119 static int hf_smb_flags_response = -1;
120 static int hf_smb_flags2_long_names_allowed = -1;
121 static int hf_smb_flags2_ea = -1;
122 static int hf_smb_flags2_sec_sig = -1;
123 static int hf_smb_flags2_long_names_used = -1;
124 static int hf_smb_flags2_esn = -1;
125 static int hf_smb_flags2_dfs = -1;
126 static int hf_smb_flags2_roe = -1;
127 static int hf_smb_flags2_nt_error = -1;
128 static int hf_smb_flags2_string = -1;
129 static int hf_smb_word_count = -1;
130 static int hf_smb_byte_count = -1;
131 static int hf_smb_buffer_format = -1;
132 static int hf_smb_dialect_name = -1;
133 static int hf_smb_dialect_index = -1;
134 static int hf_smb_max_trans_buf_size = -1;
135 static int hf_smb_max_mpx_count = -1;
136 static int hf_smb_max_vcs_num = -1;
137 static int hf_smb_session_key = -1;
138 static int hf_smb_server_timezone = -1;
139 static int hf_smb_encryption_key_length = -1;
140 static int hf_smb_encryption_key = -1;
141 static int hf_smb_primary_domain = -1;
142 static int hf_smb_server = -1;
143 static int hf_smb_max_raw_buf_size = -1;
144 static int hf_smb_server_guid = -1;
145 static int hf_smb_security_blob_len = -1;
146 static int hf_smb_security_blob = -1;
147 static int hf_smb_sm_mode16 = -1;
148 static int hf_smb_sm_password16 = -1;
149 static int hf_smb_sm_mode = -1;
150 static int hf_smb_sm_password = -1;
151 static int hf_smb_sm_signatures = -1;
152 static int hf_smb_sm_sig_required = -1;
153 static int hf_smb_rm_read = -1;
154 static int hf_smb_rm_write = -1;
155 static int hf_smb_server_date_time = -1;
156 static int hf_smb_server_smb_date = -1;
157 static int hf_smb_server_smb_time = -1;
158 static int hf_smb_server_cap_raw_mode = -1;
159 static int hf_smb_server_cap_mpx_mode = -1;
160 static int hf_smb_server_cap_unicode = -1;
161 static int hf_smb_server_cap_large_files = -1;
162 static int hf_smb_server_cap_nt_smbs = -1;
163 static int hf_smb_server_cap_rpc_remote_apis = -1;
164 static int hf_smb_server_cap_nt_status = -1;
165 static int hf_smb_server_cap_level_ii_oplocks = -1;
166 static int hf_smb_server_cap_lock_and_read = -1;
167 static int hf_smb_server_cap_nt_find = -1;
168 static int hf_smb_server_cap_dfs = -1;
169 static int hf_smb_server_cap_infolevel_passthru = -1;
170 static int hf_smb_server_cap_large_readx = -1;
171 static int hf_smb_server_cap_large_writex = -1;
172 static int hf_smb_server_cap_unix = -1;
173 static int hf_smb_server_cap_reserved = -1;
174 static int hf_smb_server_cap_bulk_transfer = -1;
175 static int hf_smb_server_cap_compressed_data = -1;
176 static int hf_smb_server_cap_extended_security = -1;
177 static int hf_smb_system_time = -1;
178 static int hf_smb_unknown = -1;
179 static int hf_smb_dir_name = -1;
180 static int hf_smb_echo_count = -1;
181 static int hf_smb_echo_data = -1;
182 static int hf_smb_echo_seq_num = -1;
183 static int hf_smb_max_buf_size = -1;
184 static int hf_smb_password = -1;
185 static int hf_smb_password_len = -1;
186 static int hf_smb_ansi_password = -1;
187 static int hf_smb_ansi_password_len = -1;
188 static int hf_smb_unicode_password = -1;
189 static int hf_smb_unicode_password_len = -1;
190 static int hf_smb_path = -1;
191 static int hf_smb_service = -1;
192 static int hf_smb_move_flags_file = -1;
193 static int hf_smb_move_flags_dir = -1;
194 static int hf_smb_move_flags_verify = -1;
195 static int hf_smb_files_moved = -1;
196 static int hf_smb_copy_flags_file = -1;
197 static int hf_smb_copy_flags_dir = -1;
198 static int hf_smb_copy_flags_dest_mode = -1;
199 static int hf_smb_copy_flags_source_mode = -1;
200 static int hf_smb_copy_flags_verify = -1;
201 static int hf_smb_copy_flags_tree_copy = -1;
202 static int hf_smb_copy_flags_ea_action = -1;
203 static int hf_smb_count = -1;
204 static int hf_smb_file_name = -1;
205 static int hf_smb_open_function_open = -1;
206 static int hf_smb_open_function_create = -1;
207 static int hf_smb_fid = -1;
208 static int hf_smb_file_attr_read_only_16bit = -1;
209 static int hf_smb_file_attr_read_only_8bit = -1;
210 static int hf_smb_file_attr_hidden_16bit = -1;
211 static int hf_smb_file_attr_hidden_8bit = -1;
212 static int hf_smb_file_attr_system_16bit = -1;
213 static int hf_smb_file_attr_system_8bit = -1;
214 static int hf_smb_file_attr_volume_16bit = -1;
215 static int hf_smb_file_attr_volume_8bit = -1;
216 static int hf_smb_file_attr_directory_16bit = -1;
217 static int hf_smb_file_attr_directory_8bit = -1;
218 static int hf_smb_file_attr_archive_16bit = -1;
219 static int hf_smb_file_attr_archive_8bit = -1;
220 static int hf_smb_file_attr_device = -1;
221 static int hf_smb_file_attr_normal = -1;
222 static int hf_smb_file_attr_temporary = -1;
223 static int hf_smb_file_attr_sparse = -1;
224 static int hf_smb_file_attr_reparse = -1;
225 static int hf_smb_file_attr_compressed = -1;
226 static int hf_smb_file_attr_offline = -1;
227 static int hf_smb_file_attr_not_content_indexed = -1;
228 static int hf_smb_file_attr_encrypted = -1;
229 static int hf_smb_file_size = -1;
230 static int hf_smb_search_attribute_read_only = -1;
231 static int hf_smb_search_attribute_hidden = -1;
232 static int hf_smb_search_attribute_system = -1;
233 static int hf_smb_search_attribute_volume = -1;
234 static int hf_smb_search_attribute_directory = -1;
235 static int hf_smb_search_attribute_archive = -1;
236 static int hf_smb_access_mode = -1;
237 static int hf_smb_access_sharing = -1;
238 static int hf_smb_access_locality = -1;
239 static int hf_smb_access_caching = -1;
240 static int hf_smb_access_writetru = -1;
241 static int hf_smb_create_time = -1;
242 static int hf_smb_modify_time = -1;
243 static int hf_smb_backup_time = -1;
244 static int hf_smb_mac_alloc_block_count = -1;
245 static int hf_smb_mac_alloc_block_size = -1;
246 static int hf_smb_mac_free_block_count = -1;
247 static int hf_smb_mac_fndrinfo = -1;
248 static int hf_smb_mac_root_file_count = -1;
249 static int hf_smb_mac_root_dir_count = -1;
250 static int hf_smb_mac_file_count = -1;
251 static int hf_smb_mac_dir_count = -1;
252 static int hf_smb_mac_support_flags = -1;
253 static int hf_smb_mac_sup_access_ctrl = -1;
254 static int hf_smb_mac_sup_getset_comments = -1;
255 static int hf_smb_mac_sup_desktopdb_calls = -1;
256 static int hf_smb_mac_sup_unique_ids = -1;
257 static int hf_smb_mac_sup_streams = -1;
258 static int hf_smb_create_dos_date = -1;
259 static int hf_smb_create_dos_time = -1;
260 static int hf_smb_last_write_time = -1;
261 static int hf_smb_last_write_dos_date = -1;
262 static int hf_smb_last_write_dos_time = -1;
263 static int hf_smb_access_time = -1;
264 static int hf_smb_access_dos_date = -1;
265 static int hf_smb_access_dos_time = -1;
266 static int hf_smb_old_file_name = -1;
267 static int hf_smb_offset = -1;
268 static int hf_smb_remaining = -1;
269 static int hf_smb_padding = -1;
270 static int hf_smb_file_data = -1;
271 static int hf_smb_total_data_len = -1;
272 static int hf_smb_data_len = -1;
273 static int hf_smb_seek_mode = -1;
274 static int hf_smb_data_size = -1;
275 static int hf_smb_alloc_size = -1;
276 static int hf_smb_alloc_size64 = -1;
277 static int hf_smb_max_count = -1;
278 static int hf_smb_min_count = -1;
279 static int hf_smb_timeout = -1;
280 static int hf_smb_high_offset = -1;
281 static int hf_smb_units = -1;
282 static int hf_smb_bpu = -1;
283 static int hf_smb_blocksize = -1;
284 static int hf_smb_freeunits = -1;
285 static int hf_smb_data_offset = -1;
286 static int hf_smb_dcm = -1;
287 static int hf_smb_request_mask = -1;
288 static int hf_smb_response_mask = -1;
289 static int hf_smb_search_id = -1;
290 static int hf_smb_write_mode_write_through = -1;
291 static int hf_smb_write_mode_return_remaining = -1;
292 static int hf_smb_write_mode_raw = -1;
293 static int hf_smb_write_mode_message_start = -1;
294 static int hf_smb_write_mode_connectionless = -1;
295 static int hf_smb_resume_key_len = -1;
296 static int hf_smb_resume_find_id = -1;
297 static int hf_smb_resume_server_cookie = -1;
298 static int hf_smb_resume_client_cookie = -1;
299 static int hf_smb_andxoffset = -1;
300 static int hf_smb_lock_type_large = -1;
301 static int hf_smb_lock_type_cancel = -1;
302 static int hf_smb_lock_type_change = -1;
303 static int hf_smb_lock_type_oplock = -1;
304 static int hf_smb_lock_type_shared = -1;
305 static int hf_smb_locking_ol = -1;
306 static int hf_smb_number_of_locks = -1;
307 static int hf_smb_number_of_unlocks = -1;
308 static int hf_smb_lock_long_offset = -1;
309 static int hf_smb_lock_long_length = -1;
310 static int hf_smb_file_type = -1;
311 static int hf_smb_ipc_state_nonblocking = -1;
312 static int hf_smb_ipc_state_endpoint = -1;
313 static int hf_smb_ipc_state_pipe_type = -1;
314 static int hf_smb_ipc_state_read_mode = -1;
315 static int hf_smb_ipc_state_icount = -1;
316 static int hf_smb_server_fid = -1;
317 static int hf_smb_open_flags_add_info = -1;
318 static int hf_smb_open_flags_ex_oplock = -1;
319 static int hf_smb_open_flags_batch_oplock = -1;
320 static int hf_smb_open_flags_ealen = -1;
321 static int hf_smb_open_action_open = -1;
322 static int hf_smb_open_action_lock = -1;
323 static int hf_smb_vc_num = -1;
324 static int hf_smb_account = -1;
325 static int hf_smb_os = -1;
326 static int hf_smb_lanman = -1;
327 static int hf_smb_setup_action_guest = -1;
328 static int hf_smb_fs = -1;
329 static int hf_smb_connect_flags_dtid = -1;
330 static int hf_smb_connect_support_search = -1;
331 static int hf_smb_connect_support_in_dfs = -1;
332 static int hf_smb_max_setup_count = -1;
333 static int hf_smb_total_param_count = -1;
334 static int hf_smb_total_data_count = -1;
335 static int hf_smb_max_param_count = -1;
336 static int hf_smb_max_data_count = -1;
337 static int hf_smb_param_disp16 = -1;
338 static int hf_smb_param_count16 = -1;
339 static int hf_smb_param_offset16 = -1;
340 static int hf_smb_param_disp32 = -1;
341 static int hf_smb_param_count32 = -1;
342 static int hf_smb_param_offset32 = -1;
343 static int hf_smb_data_disp16 = -1;
344 static int hf_smb_data_count16 = -1;
345 static int hf_smb_data_offset16 = -1;
346 static int hf_smb_data_disp32 = -1;
347 static int hf_smb_data_count32 = -1;
348 static int hf_smb_data_offset32 = -1;
349 static int hf_smb_setup_count = -1;
350 static int hf_smb_nt_trans_subcmd = -1;
351 static int hf_smb_nt_ioctl_function_code = -1;
352 static int hf_smb_nt_ioctl_isfsctl = -1;
353 static int hf_smb_nt_ioctl_flags_root_handle = -1;
354 static int hf_smb_nt_ioctl_data = -1;
355 #ifdef SMB_UNUSED_HANDLES
356 static int hf_smb_nt_security_information = -1;
357 #endif
358 static int hf_smb_nt_notify_action = -1;
359 static int hf_smb_nt_notify_watch_tree = -1;
360 static int hf_smb_nt_notify_stream_write = -1;
361 static int hf_smb_nt_notify_stream_size = -1;
362 static int hf_smb_nt_notify_stream_name = -1;
363 static int hf_smb_nt_notify_security = -1;
364 static int hf_smb_nt_notify_ea = -1;
365 static int hf_smb_nt_notify_creation = -1;
366 static int hf_smb_nt_notify_last_access = -1;
367 static int hf_smb_nt_notify_last_write = -1;
368 static int hf_smb_nt_notify_size = -1;
369 static int hf_smb_nt_notify_attributes = -1;
370 static int hf_smb_nt_notify_dir_name = -1;
371 static int hf_smb_nt_notify_file_name = -1;
372 static int hf_smb_root_dir_fid = -1;
373 static int hf_smb_nt_create_disposition = -1;
374 static int hf_smb_sd_length = -1;
375 static int hf_smb_ea_list_length = -1;
376 static int hf_smb_ea_flags = -1;
377 static int hf_smb_ea_name_length = -1;
378 static int hf_smb_ea_data_length = -1;
379 static int hf_smb_ea_name = -1;
380 static int hf_smb_ea_data = -1;
381 static int hf_smb_file_name_len = -1;
382 static int hf_smb_nt_impersonation_level = -1;
383 static int hf_smb_nt_security_flags_context_tracking = -1;
384 static int hf_smb_nt_security_flags_effective_only = -1;
385 static int hf_smb_nt_access_mask_generic_read = -1;
386 static int hf_smb_nt_access_mask_generic_write = -1;
387 static int hf_smb_nt_access_mask_generic_execute = -1;
388 static int hf_smb_nt_access_mask_generic_all = -1;
389 static int hf_smb_nt_access_mask_maximum_allowed = -1;
390 static int hf_smb_nt_access_mask_system_security = -1;
391 static int hf_smb_nt_access_mask_synchronize = -1;
392 static int hf_smb_nt_access_mask_write_owner = -1;
393 static int hf_smb_nt_access_mask_write_dac = -1;
394 static int hf_smb_nt_access_mask_read_control = -1;
395 static int hf_smb_nt_access_mask_delete = -1;
396 static int hf_smb_nt_access_mask_write_attributes = -1;
397 static int hf_smb_nt_access_mask_read_attributes = -1;
398 static int hf_smb_nt_access_mask_delete_child = -1;
399 static int hf_smb_nt_access_mask_execute = -1;
400 static int hf_smb_nt_access_mask_write_ea = -1;
401 static int hf_smb_nt_access_mask_read_ea = -1;
402 static int hf_smb_nt_access_mask_append = -1;
403 static int hf_smb_nt_access_mask_write = -1;
404 static int hf_smb_nt_access_mask_read = -1;
405 static int hf_smb_nt_create_bits_oplock = -1;
406 static int hf_smb_nt_create_bits_boplock = -1;
407 static int hf_smb_nt_create_bits_dir = -1;
408 static int hf_smb_nt_create_bits_ext_resp = -1;
409 static int hf_smb_nt_create_options_directory_file = -1;
410 static int hf_smb_nt_create_options_write_through = -1;
411 static int hf_smb_nt_create_options_sequential_only = -1;
412 static int hf_smb_nt_create_options_sync_io_alert = -1;
413 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
414 static int hf_smb_nt_create_options_non_directory_file = -1;
415 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
416 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
417 static int hf_smb_nt_create_options_random_access = -1;
418 static int hf_smb_nt_create_options_delete_on_close = -1;
419 static int hf_smb_nt_share_access_read = -1;
420 static int hf_smb_nt_share_access_write = -1;
421 static int hf_smb_nt_share_access_delete = -1;
422 static int hf_smb_file_eattr_read_only = -1;
423 static int hf_smb_file_eattr_hidden = -1;
424 static int hf_smb_file_eattr_system = -1;
425 static int hf_smb_file_eattr_volume = -1;
426 static int hf_smb_file_eattr_directory = -1;
427 static int hf_smb_file_eattr_archive = -1;
428 static int hf_smb_file_eattr_device = -1;
429 static int hf_smb_file_eattr_normal = -1;
430 static int hf_smb_file_eattr_temporary = -1;
431 static int hf_smb_file_eattr_sparse = -1;
432 static int hf_smb_file_eattr_reparse = -1;
433 static int hf_smb_file_eattr_compressed = -1;
434 static int hf_smb_file_eattr_offline = -1;
435 static int hf_smb_file_eattr_not_content_indexed = -1;
436 static int hf_smb_file_eattr_encrypted = -1;
437 static int hf_smb_sec_desc_len = -1;
438 static int hf_smb_sec_desc_revision = -1;
439 static int hf_smb_sec_desc_type_owner_defaulted = -1;
440 static int hf_smb_sec_desc_type_group_defaulted = -1;
441 static int hf_smb_sec_desc_type_dacl_present = -1;
442 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
443 static int hf_smb_sec_desc_type_sacl_present = -1;
444 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
445 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
446 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
447 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
448 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
449 static int hf_smb_sec_desc_type_dacl_protected = -1;
450 static int hf_smb_sec_desc_type_sacl_protected = -1;
451 static int hf_smb_sec_desc_type_self_relative = -1;
452 static int hf_smb_sid = -1;
453 static int hf_smb_sid_revision = -1;
454 static int hf_smb_sid_num_auth = -1;
455 static int hf_smb_acl_revision = -1;
456 static int hf_smb_acl_size = -1;
457 static int hf_smb_acl_num_aces = -1;
458 static int hf_smb_ace_type = -1;
459 static int hf_smb_ace_size = -1;
460 static int hf_smb_ace_flags_object_inherit = -1;
461 static int hf_smb_ace_flags_container_inherit = -1;
462 static int hf_smb_ace_flags_non_propagate_inherit = -1;
463 static int hf_smb_ace_flags_inherit_only = -1;
464 static int hf_smb_ace_flags_inherited_ace = -1;
465 static int hf_smb_ace_flags_successful_access = -1;
466 static int hf_smb_ace_flags_failed_access = -1;
467 static int hf_smb_nt_qsd_owner = -1;
468 static int hf_smb_nt_qsd_group = -1;
469 static int hf_smb_nt_qsd_dacl = -1;
470 static int hf_smb_nt_qsd_sacl = -1;
471 static int hf_smb_extended_attributes = -1;
472 static int hf_smb_oplock_level = -1;
473 static int hf_smb_create_action = -1;
474 static int hf_smb_file_id = -1;
475 static int hf_smb_ea_error_offset = -1;
476 static int hf_smb_end_of_file = -1;
477 static int hf_smb_device_type = -1;
478 static int hf_smb_is_directory = -1;
479 static int hf_smb_next_entry_offset = -1;
480 static int hf_smb_change_time = -1;
481 static int hf_smb_setup_len = -1;
482 static int hf_smb_print_mode = -1;
483 static int hf_smb_print_identifier = -1;
484 static int hf_smb_restart_index = -1;
485 static int hf_smb_print_queue_date = -1;
486 static int hf_smb_print_queue_dos_date = -1;
487 static int hf_smb_print_queue_dos_time = -1;
488 static int hf_smb_print_status = -1;
489 static int hf_smb_print_spool_file_number = -1;
490 static int hf_smb_print_spool_file_size = -1;
491 static int hf_smb_print_spool_file_name = -1;
492 static int hf_smb_start_index = -1;
493 static int hf_smb_originator_name = -1;
494 static int hf_smb_destination_name = -1;
495 static int hf_smb_message_len = -1;
496 static int hf_smb_message = -1;
497 static int hf_smb_mgid = -1;
498 static int hf_smb_forwarded_name = -1;
499 static int hf_smb_machine_name = -1;
500 static int hf_smb_cancel_to = -1;
501 static int hf_smb_trans2_subcmd = -1;
502 static int hf_smb_trans_name = -1;
503 static int hf_smb_transaction_flags_dtid = -1;
504 static int hf_smb_transaction_flags_owt = -1;
505 static int hf_smb_search_count = -1;
506 static int hf_smb_search_pattern = -1;
507 static int hf_smb_ff2_backup = -1;
508 static int hf_smb_ff2_continue = -1;
509 static int hf_smb_ff2_resume = -1;
510 static int hf_smb_ff2_close_eos = -1;
511 static int hf_smb_ff2_close = -1;
512 static int hf_smb_ff2_information_level = -1;
513 static int hf_smb_qpi_loi = -1;
514 static int hf_smb_spi_loi = -1;
515 #if 0
516 static int hf_smb_sfi_writetru = -1;
517 static int hf_smb_sfi_caching = -1;
518 #endif
519 static int hf_smb_storage_type = -1;
520 static int hf_smb_resume = -1;
521 static int hf_smb_max_referral_level = -1;
522 static int hf_smb_qfsi_information_level = -1;
523 static int hf_smb_number_of_links = -1;
524 static int hf_smb_delete_pending = -1;
525 static int hf_smb_index_number = -1;
526 static int hf_smb_current_offset = -1;
527 static int hf_smb_t2_alignment = -1;
528 static int hf_smb_t2_stream_name_length = -1;
529 static int hf_smb_t2_stream_size = -1;
530 static int hf_smb_t2_stream_name = -1;
531 static int hf_smb_t2_compressed_file_size = -1;
532 static int hf_smb_t2_compressed_format = -1;
533 static int hf_smb_t2_compressed_unit_shift = -1;
534 static int hf_smb_t2_compressed_chunk_shift = -1;
535 static int hf_smb_t2_compressed_cluster_shift = -1;
536 static int hf_smb_t2_marked_for_deletion = -1;
537 static int hf_smb_dfs_path_consumed = -1;
538 static int hf_smb_dfs_num_referrals = -1;
539 static int hf_smb_get_dfs_server_hold_storage = -1;
540 static int hf_smb_get_dfs_fielding = -1;
541 static int hf_smb_dfs_referral_version = -1;
542 static int hf_smb_dfs_referral_size = -1;
543 static int hf_smb_dfs_referral_server_type = -1;
544 static int hf_smb_dfs_referral_flags_strip = -1;
545 static int hf_smb_dfs_referral_node_offset = -1;
546 static int hf_smb_dfs_referral_node = -1;
547 static int hf_smb_dfs_referral_proximity = -1;
548 static int hf_smb_dfs_referral_ttl = -1;
549 static int hf_smb_dfs_referral_path_offset = -1;
550 static int hf_smb_dfs_referral_path = -1;
551 static int hf_smb_dfs_referral_alt_path_offset = -1;
552 static int hf_smb_dfs_referral_alt_path = -1;
553 static int hf_smb_end_of_search = -1;
554 static int hf_smb_last_name_offset = -1;
555 static int hf_smb_fn_information_level = -1;
556 static int hf_smb_monitor_handle = -1;
557 static int hf_smb_change_count = -1;
558 static int hf_smb_file_index = -1;
559 static int hf_smb_short_file_name = -1;
560 static int hf_smb_short_file_name_len = -1;
561 static int hf_smb_fs_id = -1;
562 static int hf_smb_sector_unit = -1;
563 static int hf_smb_fs_units = -1;
564 static int hf_smb_fs_sector = -1;
565 static int hf_smb_avail_units = -1;
566 static int hf_smb_volume_serial_num = -1;
567 static int hf_smb_volume_label_len = -1;
568 static int hf_smb_volume_label = -1;
569 static int hf_smb_free_alloc_units64 = -1;
570 static int hf_smb_caller_free_alloc_units64 = -1;
571 static int hf_smb_actual_free_alloc_units64 = -1;
572 static int hf_smb_max_name_len = -1;
573 static int hf_smb_fs_name_len = -1;
574 static int hf_smb_fs_name = -1;
575 static int hf_smb_device_char_removable = -1;
576 static int hf_smb_device_char_read_only = -1;
577 static int hf_smb_device_char_floppy = -1;
578 static int hf_smb_device_char_write_once = -1;
579 static int hf_smb_device_char_remote = -1;
580 static int hf_smb_device_char_mounted = -1;
581 static int hf_smb_device_char_virtual = -1;
582 static int hf_smb_fs_attr_css = -1;
583 static int hf_smb_fs_attr_cpn = -1;
584 static int hf_smb_fs_attr_pacls = -1;
585 static int hf_smb_fs_attr_fc = -1;
586 static int hf_smb_fs_attr_vq = -1;
587 static int hf_smb_fs_attr_dim = -1;
588 static int hf_smb_fs_attr_vic = -1;
589 static int hf_smb_quota_flags_enabled = -1;
590 static int hf_smb_quota_flags_deny_disk = -1;
591 static int hf_smb_quota_flags_log_limit = -1;
592 static int hf_smb_quota_flags_log_warning = -1;
593 static int hf_smb_soft_quota_limit = -1;
594 static int hf_smb_hard_quota_limit = -1;
595 static int hf_smb_user_quota_used = -1;
596 static int hf_smb_user_quota_offset = -1;
597 static int hf_smb_nt_rename_level = -1;
598 static int hf_smb_cluster_count = -1;
599 static int hf_smb_segments = -1;
600 static int hf_smb_segment = -1;
601 static int hf_smb_segment_overlap = -1;
602 static int hf_smb_segment_overlap_conflict = -1;
603 static int hf_smb_segment_multiple_tails = -1;
604 static int hf_smb_segment_too_long_fragment = -1;
605 static int hf_smb_segment_error = -1;
606 static int hf_smb_pipe_write_len = -1;
607 static int hf_smb_unix_major_version = -1;
608 static int hf_smb_unix_minor_version = -1;
609 static int hf_smb_unix_capability_fcntl = -1;
610 static int hf_smb_unix_capability_posix_acl = -1;
611 static int hf_smb_unix_file_size = -1;
612 static int hf_smb_unix_file_num_bytes = -1;
613 static int hf_smb_unix_file_last_status = -1;
614 static int hf_smb_unix_file_last_access = -1;
615 static int hf_smb_unix_file_last_change = -1;
616 static int hf_smb_unix_file_uid = -1;
617 static int hf_smb_unix_file_gid = -1;
618 static int hf_smb_unix_file_type = -1;
619 static int hf_smb_unix_file_dev_major = -1;
620 static int hf_smb_unix_file_dev_minor = -1;
621 static int hf_smb_unix_file_unique_id = -1;
622 static int hf_smb_unix_file_permissions = -1;
623 static int hf_smb_unix_file_nlinks = -1;
624 static int hf_smb_unix_file_link_dest = -1;
625 static int hf_smb_unix_find_file_nextoffset = -1;
626 static int hf_smb_unix_find_file_resumekey = -1;
627
628 static gint ett_smb = -1;
629 static gint ett_smb_hdr = -1;
630 static gint ett_smb_command = -1;
631 static gint ett_smb_fileattributes = -1;
632 static gint ett_smb_capabilities = -1;
633 static gint ett_smb_aflags = -1;
634 static gint ett_smb_dialect = -1;
635 static gint ett_smb_dialects = -1;
636 static gint ett_smb_mode = -1;
637 static gint ett_smb_rawmode = -1;
638 static gint ett_smb_flags = -1;
639 static gint ett_smb_flags2 = -1;
640 static gint ett_smb_desiredaccess = -1;
641 static gint ett_smb_search = -1;
642 static gint ett_smb_file = -1;
643 static gint ett_smb_openfunction = -1;
644 static gint ett_smb_filetype = -1;
645 static gint ett_smb_openaction = -1;
646 static gint ett_smb_writemode = -1;
647 static gint ett_smb_lock_type = -1;
648 static gint ett_smb_ssetupandxaction = -1;
649 static gint ett_smb_optionsup = -1;
650 static gint ett_smb_time_date = -1;
651 static gint ett_smb_move_copy_flags = -1;
652 static gint ett_smb_file_attributes = -1;
653 static gint ett_smb_search_resume_key = -1;
654 static gint ett_smb_search_dir_info = -1;
655 static gint ett_smb_unlocks = -1;
656 static gint ett_smb_unlock = -1;
657 static gint ett_smb_locks = -1;
658 static gint ett_smb_lock = -1;
659 static gint ett_smb_open_flags = -1;
660 static gint ett_smb_ipc_state = -1;
661 static gint ett_smb_open_action = -1;
662 static gint ett_smb_setup_action = -1;
663 static gint ett_smb_connect_flags = -1;
664 static gint ett_smb_connect_support_bits = -1;
665 static gint ett_smb_nt_access_mask = -1;
666 static gint ett_smb_nt_create_bits = -1;
667 static gint ett_smb_nt_create_options = -1;
668 static gint ett_smb_nt_share_access = -1;
669 static gint ett_smb_nt_security_flags = -1;
670 static gint ett_smb_nt_trans_setup = -1;
671 static gint ett_smb_nt_trans_data = -1;
672 static gint ett_smb_nt_trans_param = -1;
673 static gint ett_smb_nt_notify_completion_filter = -1;
674 static gint ett_smb_nt_ioctl_flags = -1;
675 static gint ett_smb_security_information_mask = -1;
676 static gint ett_smb_print_queue_entry = -1;
677 static gint ett_smb_transaction_flags = -1;
678 static gint ett_smb_transaction_params = -1;
679 static gint ett_smb_find_first2_flags = -1;
680 static gint ett_smb_mac_support_flags = -1;
681 #if 0
682 static gint ett_smb_ioflag = -1;
683 #endif
684 static gint ett_smb_transaction_data = -1;
685 static gint ett_smb_stream_info = -1;
686 static gint ett_smb_dfs_referrals = -1;
687 static gint ett_smb_dfs_referral = -1;
688 static gint ett_smb_dfs_referral_flags = -1;
689 static gint ett_smb_get_dfs_flags = -1;
690 static gint ett_smb_ff2_data = -1;
691 static gint ett_smb_device_characteristics = -1;
692 static gint ett_smb_fs_attributes = -1;
693 static gint ett_smb_segments = -1;
694 static gint ett_smb_segment = -1;
695 static gint ett_smb_sec_desc = -1;
696 static gint ett_smb_sid = -1;
697 static gint ett_smb_acl = -1;
698 static gint ett_smb_ace = -1;
699 static gint ett_smb_ace_flags = -1;
700 static gint ett_smb_sec_desc_type = -1;
701 static gint ett_smb_quotaflags = -1;
702 static gint ett_smb_secblob = -1;
703 static gint ett_smb_unicode_password = -1;
704 static gint ett_smb_ea = -1;
705 static gint ett_smb_unix_capabilities = -1;
706
707 static int smb_tap = -1;
708
709 static dissector_handle_t gssapi_handle = NULL;
710 static dissector_handle_t ntlmssp_handle = NULL;
711
712 static const fragment_items smb_frag_items = {
713         &ett_smb_segment,
714         &ett_smb_segments,
715
716         &hf_smb_segments,
717         &hf_smb_segment,
718         &hf_smb_segment_overlap,
719         &hf_smb_segment_overlap_conflict,
720         &hf_smb_segment_multiple_tails,
721         &hf_smb_segment_too_long_fragment,
722         &hf_smb_segment_error,
723         NULL,
724
725         "segments"
726 };
727
728 proto_tree *top_tree=NULL;     /* ugly */
729
730 static char *decode_smb_name(unsigned char);
731 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
732
733 /*
734  * Macros for use in the main dissector routines for an SMB.
735  */
736
737 #define WORD_COUNT      \
738         /* Word Count */                                \
739         wc = tvb_get_guint8(tvb, offset);               \
740         proto_tree_add_uint(tree, hf_smb_word_count,    \
741                 tvb, offset, 1, wc);                    \
742         offset += 1;                                    \
743         if(wc==0) goto bytecount;
744
745 #define BYTE_COUNT      \
746         bytecount:                                      \
747         bc = tvb_get_letohs(tvb, offset);               \
748         proto_tree_add_uint(tree, hf_smb_byte_count,    \
749                         tvb, offset, 2, bc);            \
750         offset += 2;                                    \
751         if(bc==0) goto endofcommand;
752
753 #define CHECK_BYTE_COUNT(len)   \
754         if (bc < len) goto endofcommand;
755
756 #define COUNT_BYTES(len)   {\
757         int tmp;            \
758         tmp=len;            \
759         offset += tmp;      \
760         bc -= tmp;          \
761         }
762
763 #define END_OF_SMB      \
764         if (bc != 0) { \
765                 proto_tree_add_text(tree, tvb, offset, bc, \
766                     "Extra byte parameters");           \
767                 offset += bc;                           \
768         }                                               \
769         endofcommand:
770
771 /*
772  * Macros for use in routines called by them.
773  */
774 #define CHECK_BYTE_COUNT_SUBR(len)      \
775         if (*bcp < len) {               \
776                 *trunc = TRUE;          \
777                 return offset;          \
778         }
779
780 #define CHECK_STRING_SUBR(fn)   \
781         if (fn == NULL) {       \
782                 *trunc = TRUE;  \
783                 return offset;  \
784         }
785
786 #define COUNT_BYTES_SUBR(len)   \
787         offset += len;          \
788         *bcp -= len;
789
790 /*
791  * Macros for use when dissecting transaction parameters and data
792  */
793 #define CHECK_BYTE_COUNT_TRANS(len)     \
794         if (bc < len) return offset;
795
796 #define CHECK_STRING_TRANS(fn)  \
797         if (fn == NULL) return offset;
798
799 #define COUNT_BYTES_TRANS(len)  \
800         offset += len;          \
801         bc -= len;
802
803 /*
804  * Macros for use in subrroutines dissecting transaction parameters or data
805  */
806 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
807         if (*bcp < len) return offset;
808
809 #define CHECK_STRING_TRANS_SUBR(fn)     \
810         if (fn == NULL) return offset;
811
812 #define COUNT_BYTES_TRANS_SUBR(len)     \
813         offset += len;                  \
814         *bcp -= len;
815
816
817 gboolean sid_name_snooping = FALSE;
818
819 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
820    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
821    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
822 static gboolean smb_trans_reassembly = FALSE;
823 gboolean smb_dcerpc_reassembly = FALSE;
824
825 static GHashTable *smb_trans_fragment_table = NULL;
826
827 static void
828 smb_trans_reassembly_init(void)
829 {
830         fragment_table_init(&smb_trans_fragment_table);
831 }
832
833 static fragment_data *
834 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
835                      int offset, int count, int pos, int totlen)
836 {
837         fragment_data *fd_head=NULL;
838         smb_info_t *si;
839         int more_frags;
840
841         more_frags=totlen>(pos+count);
842
843         si = (smb_info_t *)pinfo->private_data;
844         if (si->sip == NULL) {
845                 /*
846                  * We don't have the frame number of the request.
847                  *
848                  * XXX - is there truly nothing we can do here?
849                  * Can we not separately keep track of the original
850                  * transaction and its continuations, as we did
851                  * at one time?
852                  *
853                  * It is probably not much point in even trying to do something here
854                  * if we have never seen the initial request. Without the initial
855                  * request we probably miss all parameters and the begining of data
856                  * so we cant even call a subdissector since we can not determine
857                  * which type of transaction call this is.
858                  */
859                 return NULL;
860         }
861
862         if(!pinfo->fd->flags.visited){
863                 fd_head = fragment_add(tvb, offset, pinfo,
864                                        si->sip->frame_req, smb_trans_fragment_table,
865                                        pos, count, more_frags);
866         } else {
867                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
868         }
869
870         /* we only show the defragmented packet for the first fragment,
871            or else we might end up with dissecting one HUGE transaction PDU
872            a LOT of times. (first fragment is the only one containing the setup
873            bytes)
874            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
875            SMBs. Takes a LOT of time dissecting and is not fun.
876         */
877         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
878                 return fd_head;
879         } else {
880                 return NULL;
881         }
882 }
883
884
885
886
887
888 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
889    These variables and functions are used to match
890    responses with calls
891    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
892 /*
893  * The information we need to save about a request in order to show the
894  * frame number of the request in the dissection of the reply.
895  */
896 typedef struct  {
897         guint32 frame;
898         guint32 pid_mid;
899 } smb_saved_info_key_t;
900
901 static GMemChunk *smb_saved_info_key_chunk = NULL;
902 static GMemChunk *smb_saved_info_chunk = NULL;
903 static int smb_saved_info_init_count = 200;
904
905 /* unmatched smb_saved_info structures.
906    For unmatched smb_saved_info structures we store the smb_saved_info
907    structure using the MID and the PID as the key.
908
909    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
910    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
911    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
912 */
913 static gint
914 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
915 {
916         register guint32 key1 = (guint32)k1;
917         register guint32 key2 = (guint32)k2;
918         return key1==key2;
919 }
920 static guint
921 smb_saved_info_hash_unmatched(gconstpointer k)
922 {
923         register guint32 key = (guint32)k;
924         return key;
925 }
926
927 /* matched smb_saved_info structures.
928    For matched smb_saved_info structures we store the smb_saved_info
929    structure twice in the table using the frame number, and a combination
930    of the MID and the PID, as the key.
931    The frame number is guaranteed to be unique but if ever someone makes
932    some change that will renumber the frames in a capture we are in BIG trouble.
933    This is not likely though since that would break (among other things) all the
934    reassembly routines as well.
935
936    We also need the MID as there may be more than one SMB request or reply
937    in a single frame, and we also need the PID as there may be more than
938    one outstanding request with the same MID and different PIDs.
939 */
940 static gint
941 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
942 {
943         const smb_saved_info_key_t *key1 = k1;
944         const smb_saved_info_key_t *key2 = k2;
945         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
946 }
947 static guint
948 smb_saved_info_hash_matched(gconstpointer k)
949 {
950         const smb_saved_info_key_t *key = k;
951         return key->frame + key->pid_mid;
952 }
953
954 static GMemChunk *smb_nt_transact_info_chunk = NULL;
955 static int smb_nt_transact_info_init_count = 200;
956
957 static GMemChunk *smb_transact2_info_chunk = NULL;
958 static int smb_transact2_info_init_count = 200;
959
960 /*
961  * The information we need to save about a Transaction request in order
962  * to dissect the reply; this includes information for use by the
963  * Remote API dissector.
964  */
965 static GMemChunk *smb_transact_info_chunk = NULL;
966 static int smb_transact_info_init_count = 200;
967
968 static GMemChunk *conv_tables_chunk = NULL;
969 static GSList *conv_tables = NULL;
970 static int conv_tables_count = 10;
971
972
973 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
974    End of request/response matching functions
975    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
976
977 static const value_string buffer_format_vals[] = {
978         {1,     "Data Block"},
979         {2,     "Dialect"},
980         {3,     "Pathname"},
981         {4,     "ASCII"},
982         {5,     "Variable Block"},
983         {0,     NULL}
984 };
985
986 /*
987  * UTIME - this is *almost* like a UNIX time stamp, except that it's
988  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
989  * January 1, 1970, 00:00:00 GMT.
990  *
991  * This means we have to do some extra work to convert it.  This code is
992  * based on the Samba code:
993  *
994  *      Unix SMB/Netbios implementation.
995  *      Version 1.9.
996  *      time handling functions
997  *      Copyright (C) Andrew Tridgell 1992-1998
998  */
999
1000 /*
1001  * Yield the difference between *A and *B, in seconds, ignoring leap
1002  * seconds.
1003  */
1004 #define TM_YEAR_BASE 1900
1005
1006 static int
1007 tm_diff(struct tm *a, struct tm *b)
1008 {
1009         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1010         int by = b->tm_year + (TM_YEAR_BASE - 1);
1011         int intervening_leap_days =
1012             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1013         int years = ay - by;
1014         int days =
1015             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1016         int hours = 24*days + (a->tm_hour - b->tm_hour);
1017         int minutes = 60*hours + (a->tm_min - b->tm_min);
1018         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1019
1020         return seconds;
1021 }
1022
1023 /*
1024  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1025  * determined.
1026  */
1027 static int
1028 TimeZone(time_t t)
1029 {
1030         struct tm *tm = gmtime(&t);
1031         struct tm tm_utc;
1032
1033         if (tm == NULL)
1034                 return 0;
1035         tm_utc = *tm;
1036         tm = localtime(&t);
1037         if (tm == NULL)
1038                 return 0;
1039         return tm_diff(&tm_utc,tm);
1040 }
1041
1042 /*
1043  * Return the same value as TimeZone, but it should be more efficient.
1044  *
1045  * We keep a table of DST offsets to prevent calling localtime() on each
1046  * call of this function. This saves a LOT of time on many unixes.
1047  *
1048  * Updated by Paul Eggert <eggert@twinsun.com>
1049  */
1050 #ifndef CHAR_BIT
1051 #define CHAR_BIT 8
1052 #endif
1053
1054 #ifndef TIME_T_MIN
1055 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1056                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1057 #endif
1058 #ifndef TIME_T_MAX
1059 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1060 #endif
1061
1062 static int
1063 TimeZoneFaster(time_t t)
1064 {
1065         static struct dst_table {time_t start,end; int zone;} *tdt;
1066         static struct dst_table *dst_table = NULL;
1067         static int table_size = 0;
1068         int i;
1069         int zone = 0;
1070
1071         if (t == 0)
1072                 t = time(NULL);
1073
1074         /* Tunis has a 8 day DST region, we need to be careful ... */
1075 #define MAX_DST_WIDTH (365*24*60*60)
1076 #define MAX_DST_SKIP (7*24*60*60)
1077
1078         for (i = 0; i < table_size; i++) {
1079                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1080                         break;
1081         }
1082
1083         if (i < table_size) {
1084                 zone = dst_table[i].zone;
1085         } else {
1086                 time_t low,high;
1087
1088                 zone = TimeZone(t);
1089                 if (dst_table == NULL)
1090                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1091                 else
1092                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1093                 if (tdt == NULL) {
1094                         if (dst_table)
1095                                 g_free(dst_table);
1096                         table_size = 0;
1097                 } else {
1098                         dst_table = tdt;
1099                         table_size++;
1100
1101                         dst_table[i].zone = zone;
1102                         dst_table[i].start = dst_table[i].end = t;
1103
1104                         /* no entry will cover more than 6 months */
1105                         low = t - MAX_DST_WIDTH/2;
1106                         if (t < low)
1107                                 low = TIME_T_MIN;
1108
1109                         high = t + MAX_DST_WIDTH/2;
1110                         if (high < t)
1111                                 high = TIME_T_MAX;
1112
1113                         /*
1114                          * Widen the new entry using two bisection searches.
1115                          */
1116                         while (low+60*60 < dst_table[i].start) {
1117                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1118                                         t = dst_table[i].start - MAX_DST_SKIP;
1119                                 else
1120                                         t = low + (dst_table[i].start-low)/2;
1121                                 if (TimeZone(t) == zone)
1122                                         dst_table[i].start = t;
1123                                 else
1124                                         low = t;
1125                         }
1126
1127                         while (high-60*60 > dst_table[i].end) {
1128                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1129                                         t = dst_table[i].end + MAX_DST_SKIP;
1130                                 else
1131                                         t = high - (high-dst_table[i].end)/2;
1132                                 if (TimeZone(t) == zone)
1133                                         dst_table[i].end = t;
1134                                 else
1135                                         high = t;
1136                         }
1137                 }
1138         }
1139         return zone;
1140 }
1141
1142 /*
1143  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1144  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1145  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1146  * daylight savings transitions because some local times are ambiguous.
1147  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1148  */
1149 static int
1150 LocTimeDiff(time_t lt)
1151 {
1152         int d = TimeZoneFaster(lt);
1153         time_t t = lt + d;
1154
1155         /* if overflow occurred, ignore all the adjustments so far */
1156         if (((t < lt) ^ (d < 0)))
1157                 t = lt;
1158
1159         /*
1160          * Now t should be close enough to the true UTC to yield the
1161          * right answer.
1162          */
1163         return TimeZoneFaster(t);
1164 }
1165
1166 static int
1167 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1168 {
1169         guint32 timeval;
1170         nstime_t ts;
1171
1172         timeval = tvb_get_letohl(tvb, offset);
1173         if (timeval == 0xffffffff) {
1174                 proto_tree_add_text(tree, tvb, offset, 4,
1175                     "%s: No time specified (0xffffffff)",
1176                     proto_registrar_get_name(hf_date));
1177                 offset += 4;
1178                 return offset;
1179         }
1180
1181         /*
1182          * We add the local time offset.
1183          */
1184         ts.secs = timeval + LocTimeDiff(timeval);
1185         ts.nsecs = 0;
1186
1187         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1188         offset += 4;
1189
1190         return offset;
1191 }
1192
1193 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1194
1195 /*
1196  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1197  * to an "nstime_t".
1198  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1199  * midnight "UTC", in 100ns units.
1200  * Return TRUE if the conversion succeeds, FALSE otherwise.
1201  *
1202  * According to the Samba code, it appears to be kludge-GMT (at least for
1203  * file listings). This means it's the GMT you get by taking a local time
1204  * and adding the server time zone offset.  This is NOT the same as GMT in
1205  * some cases.   However, we don't know the server time zone, so we don't
1206  * do that adjustment.
1207  *
1208  * This code is based on the Samba code:
1209  *
1210  *      Unix SMB/Netbios implementation.
1211  *      Version 1.9.
1212  *      time handling functions
1213  *      Copyright (C) Andrew Tridgell 1992-1998
1214  */
1215 static gboolean
1216 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1217 {
1218         double d;
1219         /* The next two lines are a fix needed for the
1220             broken SCO compiler. JRA. */
1221         time_t l_time_min = TIME_T_MIN;
1222         time_t l_time_max = TIME_T_MAX;
1223
1224         if (filetime_high == 0)
1225                 return FALSE;
1226
1227         /*
1228          * Get the time as a double, in seconds and fractional seconds.
1229          */
1230         d = ((double)filetime_high)*4.0*(double)(1<<30);
1231         d += filetime_low;
1232         d *= 1.0e-7;
1233
1234         /* Now adjust by 369 years, to make the seconds since 1970. */
1235         d -= TIME_FIXUP_CONSTANT;
1236
1237         if (!(l_time_min <= d && d <= l_time_max))
1238                 return FALSE;
1239
1240         /*
1241          * Get the time as seconds and nanoseconds.
1242          */
1243         tv->secs = d;
1244         tv->nsecs = (d - tv->secs)*1000000000;
1245
1246         return TRUE;
1247 }
1248
1249 int
1250 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1251 {
1252         guint32 filetime_high, filetime_low;
1253         nstime_t ts;
1254
1255         /* XXX there seems also to be another special time value which is fairly common :
1256            0x40000000 00000000
1257            the meaning of this one is yet unknown
1258         */
1259         if (tree) {
1260                 filetime_low = tvb_get_letohl(tvb, offset);
1261                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1262                 if (filetime_low == 0 && filetime_high == 0) {
1263                         proto_tree_add_text(tree, tvb, offset, 8,
1264                             "%s: No time specified (0)",
1265                             proto_registrar_get_name(hf_date));
1266                 } else if(filetime_low==0 && filetime_high==0x80000000){
1267                         proto_tree_add_text(tree, tvb, offset, 8,
1268                             "%s: Infinity (relative time)",
1269                             proto_registrar_get_name(hf_date));
1270                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1271                         proto_tree_add_text(tree, tvb, offset, 8,
1272                             "%s: Infinity (absolute time)",
1273                             proto_registrar_get_name(hf_date));
1274                 } else {
1275                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1276                                 proto_tree_add_time(tree, hf_date, tvb,
1277                                     offset, 8, &ts);
1278                         } else {
1279                                 proto_tree_add_text(tree, tvb, offset, 8,
1280                                     "%s: Time can't be converted",
1281                                     proto_registrar_get_name(hf_date));
1282                         }
1283                 }
1284         }
1285
1286         offset += 8;
1287         return offset;
1288 }
1289
1290 static int
1291 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1292     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1293 {
1294         guint16 dos_time, dos_date;
1295         proto_item *item = NULL;
1296         proto_tree *tree = NULL;
1297         struct tm tm;
1298         time_t t;
1299         static const int mday_noleap[12] = {
1300                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1301         };
1302         static const int mday_leap[12] = {
1303                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1304         };
1305 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1306         nstime_t tv;
1307
1308         if (time_first) {
1309                 dos_time = tvb_get_letohs(tvb, offset);
1310                 dos_date = tvb_get_letohs(tvb, offset+2);
1311         } else {
1312                 dos_date = tvb_get_letohs(tvb, offset);
1313                 dos_time = tvb_get_letohs(tvb, offset+2);
1314         }
1315
1316         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1317             (dos_date == 0 && dos_time == 0)) {
1318                 /*
1319                  * No date/time specified.
1320                  */
1321                 if(parent_tree){
1322                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1323                             "%s: No time specified (0x%08x)",
1324                             proto_registrar_get_name(hf_date),
1325                             (dos_date << 16) | dos_time);
1326                 }
1327                 offset += 4;
1328                 return offset;
1329         }
1330
1331         tm.tm_sec = (dos_time&0x1f)*2;
1332         tm.tm_min = (dos_time>>5)&0x3f;
1333         tm.tm_hour = (dos_time>>11)&0x1f;
1334         tm.tm_mday = dos_date&0x1f;
1335         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1336         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1337         tm.tm_isdst = -1;
1338
1339         /*
1340          * Do some sanity checks before calling "mktime()";
1341          * "mktime()" doesn't do them, it "normalizes" out-of-range
1342          * values.
1343          */
1344         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1345            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1346            (ISLEAP(tm.tm_year + 1900) ?
1347              tm.tm_mday > mday_leap[tm.tm_mon] :
1348              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1349              (t = mktime(&tm)) == -1) {
1350                 /*
1351                  * Invalid date/time.
1352                  */
1353                 if (parent_tree) {
1354                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1355                             "%s: Invalid time",
1356                             proto_registrar_get_name(hf_date));
1357                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1358                         if (time_first) {
1359                                 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);
1360                                 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);
1361                         } else {
1362                                 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);
1363                                 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);
1364                         }
1365                 }
1366                 offset += 4;
1367                 return offset;
1368         }
1369
1370         tv.secs = t;
1371         tv.nsecs = 0;
1372
1373         if(parent_tree){
1374                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1375                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1376                 if (time_first) {
1377                         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);
1378                         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);
1379                 } else {
1380                         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);
1381                         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);
1382                 }
1383         }
1384
1385         offset += 4;
1386
1387         return offset;
1388 }
1389
1390
1391 static const value_string da_access_vals[] = {
1392         { 0,            "Open for reading"},
1393         { 1,            "Open for writing"},
1394         { 2,            "Open for reading and writing"},
1395         { 3,            "Open for execute"},
1396         {0, NULL}
1397 };
1398 static const value_string da_sharing_vals[] = {
1399         { 0,            "Compatibility mode"},
1400         { 1,            "Deny read/write/execute (exclusive)"},
1401         { 2,            "Deny write"},
1402         { 3,            "Deny read/execute"},
1403         { 4,            "Deny none"},
1404         {0, NULL}
1405 };
1406 static const value_string da_locality_vals[] = {
1407         { 0,            "Locality of reference unknown"},
1408         { 1,            "Mainly sequential access"},
1409         { 2,            "Mainly random access"},
1410         { 3,            "Random access with some locality"},
1411         {0, NULL}
1412 };
1413 static const true_false_string tfs_da_caching = {
1414         "Do not cache this file",
1415         "Caching permitted on this file"
1416 };
1417 static const true_false_string tfs_da_writetru = {
1418         "Write through enabled",
1419         "Write through disabled"
1420 };
1421 static int
1422 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1423 {
1424         guint16 mask;
1425         proto_item *item = NULL;
1426         proto_tree *tree = NULL;
1427
1428         mask = tvb_get_letohs(tvb, offset);
1429
1430         if(parent_tree){
1431                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1432                         "%s Access: 0x%04x", type, mask);
1433                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1434         }
1435
1436         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1437                 tvb, offset, 2, mask);
1438         proto_tree_add_boolean(tree, hf_smb_access_caching,
1439                 tvb, offset, 2, mask);
1440         proto_tree_add_uint(tree, hf_smb_access_locality,
1441                 tvb, offset, 2, mask);
1442         proto_tree_add_uint(tree, hf_smb_access_sharing,
1443                 tvb, offset, 2, mask);
1444         proto_tree_add_uint(tree, hf_smb_access_mode,
1445                 tvb, offset, 2, mask);
1446
1447         offset += 2;
1448
1449         return offset;
1450 }
1451
1452 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1453 #define SMB_FILE_ATTRIBUTE_HIDDEN                       0x00000002
1454 #define SMB_FILE_ATTRIBUTE_SYSTEM                       0x00000004
1455 #define SMB_FILE_ATTRIBUTE_VOLUME                       0x00000008
1456 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1457 #define SMB_FILE_ATTRIBUTE_ARCHIVE                      0x00000020
1458 #define SMB_FILE_ATTRIBUTE_DEVICE                       0x00000040
1459 #define SMB_FILE_ATTRIBUTE_NORMAL                       0x00000080
1460 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1461 #define SMB_FILE_ATTRIBUTE_SPARSE                       0x00000200
1462 #define SMB_FILE_ATTRIBUTE_REPARSE                      0x00000400
1463 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1464 #define SMB_FILE_ATTRIBUTE_OFFLINE                      0x00001000
1465 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1466 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1467
1468 static const true_false_string tfs_file_attribute_read_only = {
1469         "This file is READ ONLY",
1470         "This file is NOT read only",
1471 };
1472 static const true_false_string tfs_file_attribute_hidden = {
1473         "This is a HIDDEN file",
1474         "This is NOT a hidden file"
1475 };
1476 static const true_false_string tfs_file_attribute_system = {
1477         "This is a SYSTEM file",
1478         "This is NOT a system file"
1479 };
1480 static const true_false_string tfs_file_attribute_volume = {
1481         "This is a VOLUME ID",
1482         "This is NOT a volume ID"
1483 };
1484 static const true_false_string tfs_file_attribute_directory = {
1485         "This is a DIRECTORY",
1486         "This is NOT a directory"
1487 };
1488 static const true_false_string tfs_file_attribute_archive = {
1489         "This file has been modified since last ARCHIVE",
1490         "This file has NOT been modified since last archive"
1491 };
1492 static const true_false_string tfs_file_attribute_device = {
1493         "This is a DEVICE",
1494         "This is NOT a device"
1495 };
1496 static const true_false_string tfs_file_attribute_normal = {
1497         "This file is an ordinary file",
1498         "This file has some attribute set"
1499 };
1500 static const true_false_string tfs_file_attribute_temporary = {
1501         "This is a TEMPORARY file",
1502         "This is NOT a temporary file"
1503 };
1504 static const true_false_string tfs_file_attribute_sparse = {
1505         "This is a SPARSE file",
1506         "This is NOT a sparse file"
1507 };
1508 static const true_false_string tfs_file_attribute_reparse = {
1509         "This file has an associated REPARSE POINT",
1510         "This file does NOT have an associated reparse point"
1511 };
1512 static const true_false_string tfs_file_attribute_compressed = {
1513         "This is a COMPRESSED file",
1514         "This is NOT a compressed file"
1515 };
1516 static const true_false_string tfs_file_attribute_offline = {
1517         "This file is OFFLINE",
1518         "This file is NOT offline"
1519 };
1520 static const true_false_string tfs_file_attribute_not_content_indexed = {
1521         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1522         "This file MAY be indexed by the content indexing service"
1523 };
1524 static const true_false_string tfs_file_attribute_encrypted = {
1525         "This is an ENCRYPTED file",
1526         "This is NOT an encrypted file"
1527 };
1528
1529 /*
1530  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1531  * listed as USHORT, and seem to be in packets in the wild, while in other
1532  * places they are listed as ULONG, and also seem to be.
1533  *
1534  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1535  * bytes to consume.
1536  */
1537
1538 static int
1539 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1540                         int bytes)
1541 {
1542         guint16 mask;
1543         proto_item *item = NULL;
1544         proto_tree *tree = NULL;
1545
1546         if (bytes != 2 && bytes != 4) {
1547
1548                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1549                 exit(1);
1550
1551         }
1552
1553         /*
1554          * The actual bits of interest appear to only be a USHORT
1555          */
1556         /* FIXME if this ever changes! */
1557         mask = tvb_get_letohs(tvb, offset);
1558
1559         if(parent_tree){
1560                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1561                         "File Attributes: 0x%08x", mask);
1562                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1563         }
1564         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1565                                tvb, offset, bytes, mask);       
1566         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1567                                tvb, offset, bytes, mask);
1568         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1569                                tvb, offset, bytes, mask);
1570         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1571                                tvb, offset, bytes, mask);
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1573                                tvb, offset, bytes, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1575                                tvb, offset, bytes, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1577                                tvb, offset, bytes, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1579                                tvb, offset, bytes, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1581                                tvb, offset, bytes, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1583                 tvb, offset, bytes, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1585                 tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1587                 tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1589                 tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1591                 tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1593                 tvb, offset, bytes, mask);
1594
1595         offset += bytes;
1596
1597         return offset;
1598 }
1599
1600 /* 3.11 */
1601 static int
1602 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1603 {
1604         guint32 mask;
1605         proto_item *item = NULL;
1606         proto_tree *tree = NULL;
1607
1608         mask = tvb_get_letohl(tvb, offset);
1609
1610         if(parent_tree){
1611                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1612                         "File Attributes: 0x%08x", mask);
1613                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1614         }
1615
1616         /*
1617          * XXX - Network Monitor disagrees on some of the
1618          * bits, e.g. the bits above temporary are "atomic write"
1619          * and "transaction write", and it says nothing about the
1620          * bits above that.
1621          *
1622          * Does the Win32 API documentation, or the NT Native API book,
1623          * suggest anything?
1624          */
1625         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1626                 tvb, offset, 4, mask);
1627         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1628                 tvb, offset, 4, mask);
1629         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1630                 tvb, offset, 4, mask);
1631         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1632                 tvb, offset, 4, mask);
1633         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1634                 tvb, offset, 4, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1636                 tvb, offset, 4, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1638                 tvb, offset, 4, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1640                 tvb, offset, 4, mask);
1641         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1642                 tvb, offset, 4, mask);
1643         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1644                 tvb, offset, 4, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1646                 tvb, offset, 4, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1648                 tvb, offset, 4, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1650                 tvb, offset, 4, mask);
1651         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1652                 tvb, offset, 4, mask);
1653         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1654                 tvb, offset, 4, mask);
1655
1656         offset += 4;
1657
1658         return offset;
1659 }
1660
1661 static int
1662 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1663 {
1664         guint8 mask;
1665         proto_item *item = NULL;
1666         proto_tree *tree = NULL;
1667
1668         mask = tvb_get_guint8(tvb, offset);
1669
1670         if(parent_tree){
1671                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1672                         "File Attributes: 0x%02x", mask);
1673                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1674         }
1675         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1676                 tvb, offset, 1, mask);
1677         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1678                 tvb, offset, 1, mask);
1679         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1680                 tvb, offset, 1, mask);
1681         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1682                 tvb, offset, 1, mask);
1683         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1684                 tvb, offset, 1, mask);
1685         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1686                 tvb, offset, 1, mask);
1687
1688         offset += 1;
1689
1690         return offset;
1691 }
1692
1693 static const true_false_string tfs_search_attribute_read_only = {
1694         "Include READ ONLY files in search results",
1695         "Do NOT include read only files in search results",
1696 };
1697 static const true_false_string tfs_search_attribute_hidden = {
1698         "Include HIDDEN files in search results",
1699         "Do NOT include hidden files in search results"
1700 };
1701 static const true_false_string tfs_search_attribute_system = {
1702         "Include SYSTEM files in search results",
1703         "Do NOT include system files in search results"
1704 };
1705 static const true_false_string tfs_search_attribute_volume = {
1706         "Include VOLUME IDs in search results",
1707         "Do NOT include volume IDs in search results"
1708 };
1709 static const true_false_string tfs_search_attribute_directory = {
1710         "Include DIRECTORIES in search results",
1711         "Do NOT include directories in search results"
1712 };
1713 static const true_false_string tfs_search_attribute_archive = {
1714         "Include ARCHIVE files in search results",
1715         "Do NOT include archive files in search results"
1716 };
1717
1718 static int
1719 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1720 {
1721         guint16 mask;
1722         proto_item *item = NULL;
1723         proto_tree *tree = NULL;
1724
1725         mask = tvb_get_letohs(tvb, offset);
1726
1727         if(parent_tree){
1728                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1729                         "Search Attributes: 0x%04x", mask);
1730                 tree = proto_item_add_subtree(item, ett_smb_search);
1731         }
1732
1733         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1734                 tvb, offset, 2, mask);
1735         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1736                 tvb, offset, 2, mask);
1737         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1738                 tvb, offset, 2, mask);
1739         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1740                 tvb, offset, 2, mask);
1741         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1742                 tvb, offset, 2, mask);
1743         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1744                 tvb, offset, 2, mask);
1745
1746         offset += 2;
1747         return offset;
1748 }
1749
1750 #if 0
1751 /*
1752  * XXX - this isn't used.
1753  * Is this used for anything?  NT Create AndX doesn't use it.
1754  * Is there some 16-bit attribute field with more bits than Read Only,
1755  * Hidden, System, Volume ID, Directory, and Archive?
1756  */
1757 static int
1758 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1759 {
1760         guint32 mask;
1761         proto_item *item = NULL;
1762         proto_tree *tree = NULL;
1763
1764         mask = tvb_get_letohl(tvb, offset);
1765
1766         if(parent_tree){
1767                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1768                         "File Attributes: 0x%08x", mask);
1769                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1770         }
1771         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1772                 tvb, offset, 2, mask);
1773         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1774                 tvb, offset, 2, mask);
1775         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1776                 tvb, offset, 2, mask);
1777         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1778                 tvb, offset, 2, mask);
1779         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1780                 tvb, offset, 2, mask);
1781         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1782                 tvb, offset, 2, mask);
1783         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1784                 tvb, offset, 2, mask);
1785         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1786                 tvb, offset, 2, mask);
1787         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1788                 tvb, offset, 2, mask);
1789         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1790                 tvb, offset, 2, mask);
1791         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1792                 tvb, offset, 2, mask);
1793         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1794                 tvb, offset, 2, mask);
1795         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1796                 tvb, offset, 2, mask);
1797         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1798                 tvb, offset, 2, mask);
1799         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1800                 tvb, offset, 2, mask);
1801
1802         offset += 2;
1803
1804         return offset;
1805 }
1806 #endif
1807
1808
1809 #define SERVER_CAP_RAW_MODE            0x00000001
1810 #define SERVER_CAP_MPX_MODE            0x00000002
1811 #define SERVER_CAP_UNICODE             0x00000004
1812 #define SERVER_CAP_LARGE_FILES         0x00000008
1813 #define SERVER_CAP_NT_SMBS             0x00000010
1814 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1815 #define SERVER_CAP_STATUS32            0x00000040
1816 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1817 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1818 #define SERVER_CAP_NT_FIND             0x00000200
1819 #define SERVER_CAP_DFS                 0x00001000
1820 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1821 #define SERVER_CAP_LARGE_READX         0x00004000
1822 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1823 #define SERVER_CAP_UNIX                0x00800000
1824 #define SERVER_CAP_RESERVED            0x02000000
1825 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1826 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1827 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1828 static const true_false_string tfs_server_cap_raw_mode = {
1829         "Read Raw and Write Raw are supported",
1830         "Read Raw and Write Raw are not supported"
1831 };
1832 static const true_false_string tfs_server_cap_mpx_mode = {
1833         "Read Mpx and Write Mpx are supported",
1834         "Read Mpx and Write Mpx are not supported"
1835 };
1836 static const true_false_string tfs_server_cap_unicode = {
1837         "Unicode strings are supported",
1838         "Unicode strings are not supported"
1839 };
1840 static const true_false_string tfs_server_cap_large_files = {
1841         "Large files are supported",
1842         "Large files are not supported",
1843 };
1844 static const true_false_string tfs_server_cap_nt_smbs = {
1845         "NT SMBs are supported",
1846         "NT SMBs are not supported"
1847 };
1848 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1849         "RPC remote APIs are supported",
1850         "RPC remote APIs are not supported"
1851 };
1852 static const true_false_string tfs_server_cap_nt_status = {
1853         "NT status codes are supported",
1854         "NT status codes are not supported"
1855 };
1856 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1857         "Level 2 oplocks are supported",
1858         "Level 2 oplocks are not supported"
1859 };
1860 static const true_false_string tfs_server_cap_lock_and_read = {
1861         "Lock and Read is supported",
1862         "Lock and Read is not supported"
1863 };
1864 static const true_false_string tfs_server_cap_nt_find = {
1865         "NT Find is supported",
1866         "NT Find is not supported"
1867 };
1868 static const true_false_string tfs_server_cap_dfs = {
1869         "Dfs is supported",
1870         "Dfs is not supported"
1871 };
1872 static const true_false_string tfs_server_cap_infolevel_passthru = {
1873         "NT information level request passthrough is supported",
1874         "NT information level request passthrough is not supported"
1875 };
1876 static const true_false_string tfs_server_cap_large_readx = {
1877         "Large Read andX is supported",
1878         "Large Read andX is not supported"
1879 };
1880 static const true_false_string tfs_server_cap_large_writex = {
1881         "Large Write andX is supported",
1882         "Large Write andX is not supported"
1883 };
1884 static const true_false_string tfs_server_cap_unix = {
1885         "UNIX extensions are supported",
1886         "UNIX extensions are not supported"
1887 };
1888 static const true_false_string tfs_server_cap_reserved = {
1889         "Reserved",
1890         "Reserved"
1891 };
1892 static const true_false_string tfs_server_cap_bulk_transfer = {
1893         "Bulk Read and Bulk Write are supported",
1894         "Bulk Read and Bulk Write are not supported"
1895 };
1896 static const true_false_string tfs_server_cap_compressed_data = {
1897         "Compressed data transfer is supported",
1898         "Compressed data transfer is not supported"
1899 };
1900 static const true_false_string tfs_server_cap_extended_security = {
1901         "Extended security exchanges are supported",
1902         "Extended security exchanges are not supported"
1903 };
1904 static int
1905 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1906 {
1907         guint32 mask;
1908         proto_item *item = NULL;
1909         proto_tree *tree = NULL;
1910
1911         mask = tvb_get_letohl(tvb, offset);
1912
1913         if(parent_tree){
1914                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1915                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1916         }
1917
1918         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1919                 tvb, offset, 4, mask);
1920         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1921                 tvb, offset, 4, mask);
1922         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1923                 tvb, offset, 4, mask);
1924         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1925                 tvb, offset, 4, mask);
1926         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1927                 tvb, offset, 4, mask);
1928         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1929                 tvb, offset, 4, mask);
1930         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1931                 tvb, offset, 4, mask);
1932         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1933                 tvb, offset, 4, mask);
1934         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1935                 tvb, offset, 4, mask);
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1941                 tvb, offset, 4, mask);
1942         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1943                 tvb, offset, 4, mask);
1944         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1945                 tvb, offset, 4, mask);
1946         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1947                 tvb, offset, 4, mask);
1948         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1949                 tvb, offset, 4, mask);
1950         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1951                 tvb, offset, 4, mask);
1952         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1953                 tvb, offset, 4, mask);
1954         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1955                 tvb, offset, 4, mask);
1956
1957         return mask;
1958 }
1959
1960 #define RAWMODE_READ   0x01
1961 #define RAWMODE_WRITE  0x02
1962 static const true_false_string tfs_rm_read = {
1963         "Read Raw is supported",
1964         "Read Raw is not supported"
1965 };
1966 static const true_false_string tfs_rm_write = {
1967         "Write Raw is supported",
1968         "Write Raw is not supported"
1969 };
1970
1971 static int
1972 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1973 {
1974         guint16 mask;
1975         proto_item *item = NULL;
1976         proto_tree *tree = NULL;
1977
1978         mask = tvb_get_letohs(tvb, offset);
1979
1980         if(parent_tree){
1981                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1982                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1983         }
1984
1985         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1986         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1987
1988         offset += 2;
1989
1990         return offset;
1991 }
1992
1993 #define SECURITY_MODE_MODE             0x01
1994 #define SECURITY_MODE_PASSWORD         0x02
1995 #define SECURITY_MODE_SIGNATURES       0x04
1996 #define SECURITY_MODE_SIG_REQUIRED     0x08
1997 static const true_false_string tfs_sm_mode = {
1998         "USER security mode",
1999         "SHARE security mode"
2000 };
2001 static const true_false_string tfs_sm_password = {
2002         "ENCRYPTED password. Use challenge/response",
2003         "PLAINTEXT password"
2004 };
2005 static const true_false_string tfs_sm_signatures = {
2006         "Security signatures ENABLED",
2007         "Security signatures NOT enabled"
2008 };
2009 static const true_false_string tfs_sm_sig_required = {
2010         "Security signatures REQUIRED",
2011         "Security signatures NOT required"
2012 };
2013
2014 static int
2015 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2016 {
2017         guint16 mask = 0;
2018         proto_item *item = NULL;
2019         proto_tree *tree = NULL;
2020
2021         switch(wc){
2022         case 13:
2023                 mask = tvb_get_letohs(tvb, offset);
2024                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2025                                 "Security Mode: 0x%04x", mask);
2026                 tree = proto_item_add_subtree(item, ett_smb_mode);
2027                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2028                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2029                 offset += 2;
2030                 break;
2031
2032         case 17:
2033                 mask = tvb_get_guint8(tvb, offset);
2034                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2035                                 "Security Mode: 0x%02x", mask);
2036                 tree = proto_item_add_subtree(item, ett_smb_mode);
2037                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2038                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2039                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2040                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2041                 offset += 1;
2042                 break;
2043         }
2044
2045         return offset;
2046 }
2047
2048 static int
2049 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2050 {
2051         proto_item *it = NULL;
2052         proto_tree *tr = NULL;
2053         guint16 bc;
2054         guint8 wc;
2055
2056         WORD_COUNT;
2057
2058         BYTE_COUNT;
2059
2060         if(tree){
2061                 it = proto_tree_add_text(tree, tvb, offset, bc,
2062                                 "Requested Dialects");
2063                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2064         }
2065
2066         while(bc){
2067                 int len;
2068                 const guint8 *str;
2069                 proto_item *dit = NULL;
2070                 proto_tree *dtr = NULL;
2071
2072                 /* XXX - what if this runs past bc? */
2073                 len = tvb_strsize(tvb, offset+1);
2074                 str = tvb_get_ptr(tvb, offset+1, len);
2075
2076                 if(tr){
2077                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2078                                         "Dialect: %s", str);
2079                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2080                 }
2081
2082                 /* Buffer Format */
2083                 CHECK_BYTE_COUNT(1);
2084                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2085                         TRUE);
2086                 COUNT_BYTES(1);
2087
2088                 /*Dialect Name */
2089                 CHECK_BYTE_COUNT(len);
2090                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2091                         len, str);
2092                 COUNT_BYTES(len);
2093         }
2094
2095         END_OF_SMB
2096
2097         return offset;
2098 }
2099
2100 static int
2101 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2102 {
2103         smb_info_t *si = pinfo->private_data;
2104         guint8 wc;
2105         guint16 dialect;
2106         const char *dn;
2107         int dn_len;
2108         guint16 bc;
2109         guint16 ekl=0;
2110         guint32 caps=0;
2111         gint16 tz;
2112
2113         WORD_COUNT;
2114
2115         /* Dialect Index */
2116         dialect = tvb_get_letohs(tvb, offset);
2117         switch(wc){
2118         case 1:
2119                 if(dialect==0xffff){
2120                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2121                                 tvb, offset, 2, dialect,
2122                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2123                 } else {
2124                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2125                                 tvb, offset, 2, dialect);
2126                 }
2127                 break;
2128         case 13:
2129                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2130                         tvb, offset, 2, dialect,
2131                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2132                 break;
2133         case 17:
2134                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2135                         tvb, offset, 2, dialect,
2136                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2137                 break;
2138         default:
2139                 proto_tree_add_text(tree, tvb, offset, wc*2,
2140                         "Words for unknown response format");
2141                 offset += wc*2;
2142                 goto bytecount;
2143         }
2144         offset += 2;
2145
2146         switch(wc){
2147         case 13:
2148                 /* Security Mode */
2149                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2150
2151                 /* Maximum Transmit Buffer Size */
2152                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2153                         tvb, offset, 2, TRUE);
2154                 offset += 2;
2155
2156                 /* Maximum Multiplex Count */
2157                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2158                         tvb, offset, 2, TRUE);
2159                 offset += 2;
2160
2161                 /* Maximum Vcs Number */
2162                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2163                         tvb, offset, 2, TRUE);
2164                 offset += 2;
2165
2166                 /* raw mode */
2167                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2168
2169                 /* session key */
2170                 proto_tree_add_item(tree, hf_smb_session_key,
2171                         tvb, offset, 4, TRUE);
2172                 offset += 4;
2173
2174                 /* current time and date at server */
2175                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2176                     TRUE);
2177
2178                 /* time zone */
2179                 tz = tvb_get_letohs(tvb, offset);
2180                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2181                 offset += 2;
2182
2183                 /* encryption key length */
2184                 ekl = tvb_get_letohs(tvb, offset);
2185                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2186                 offset += 2;
2187
2188                 /* 2 reserved bytes */
2189                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2190                 offset += 2;
2191
2192                 break;
2193
2194         case 17:
2195                 /* Security Mode */
2196                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2197
2198                 /* Maximum Multiplex Count */
2199                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2200                         tvb, offset, 2, TRUE);
2201                 offset += 2;
2202
2203                 /* Maximum Vcs Number */
2204                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2205                         tvb, offset, 2, TRUE);
2206                 offset += 2;
2207
2208                 /* Maximum Transmit Buffer Size */
2209                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2210                         tvb, offset, 4, TRUE);
2211                 offset += 4;
2212
2213                 /* maximum raw buffer size */
2214                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2215                         tvb, offset, 4, TRUE);
2216                 offset += 4;
2217
2218                 /* session key */
2219                 proto_tree_add_item(tree, hf_smb_session_key,
2220                         tvb, offset, 4, TRUE);
2221                 offset += 4;
2222
2223                 /* server capabilities */
2224                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2225                 offset += 4;
2226
2227                 /* system time */
2228                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2229                                 hf_smb_system_time);
2230
2231                 /* time zone */
2232                 tz = tvb_get_letohs(tvb, offset);
2233                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2234                         tvb, offset, 2, tz,
2235                         "Server Time Zone: %d min from UTC", tz);
2236                 offset += 2;
2237
2238                 /* encryption key length */
2239                 ekl = tvb_get_guint8(tvb, offset);
2240                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2241                         tvb, offset, 1, ekl);
2242                 offset += 1;
2243
2244                 break;
2245         }
2246
2247         BYTE_COUNT;
2248
2249         switch(wc){
2250         case 13:
2251                 /* challenge/response encryption key */
2252                 if(ekl){
2253                         CHECK_BYTE_COUNT(ekl);
2254                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2255                         COUNT_BYTES(ekl);
2256                 }
2257
2258                 /*
2259                  * Primary domain.
2260                  *
2261                  * XXX - not present if negotiated dialect isn't
2262                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2263                  * have to see the request, or assume what dialect strings
2264                  * were sent, to determine that.
2265                  *
2266                  * Is this something other than a primary domain if the
2267                  * negotiated dialect is Windows for Workgroups 3.1a?
2268                  * It appears to be 8 bytes of binary data in at least
2269                  * one capture - is that an encryption key or something
2270                  * such as that?
2271                  */
2272                 dn = get_unicode_or_ascii_string(tvb, &offset,
2273                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2274                 if (dn == NULL)
2275                         goto endofcommand;
2276                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2277                         offset, dn_len,dn);
2278                 COUNT_BYTES(dn_len);
2279                 break;
2280
2281         case 17:
2282                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2283                         /* challenge/response encryption key */
2284                         /* XXX - is this aligned on an even boundary? */
2285                         if(ekl){
2286                                 CHECK_BYTE_COUNT(ekl);
2287                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2288                                         tvb, offset, ekl, TRUE);
2289                                 COUNT_BYTES(ekl);
2290                         }
2291
2292                         /* domain */
2293                         /* this string is special, unicode is flagged in caps */
2294                         /* This string is NOT padded to be 16bit aligned.
2295                            (seen in actual capture)
2296                            XXX - I've seen a capture where it appears to be
2297                            so aligned, but I've also seen captures where
2298                            it is.  The captures where it appeared to be
2299                            aligned may have been from buggy servers. */
2300                         /* However, don't get rid of existing setting */
2301                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2302                           si->unicode;
2303
2304                         dn = get_unicode_or_ascii_string(tvb,
2305                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2306                                 &bc);
2307                         if (dn == NULL)
2308                                 goto endofcommand;
2309                         proto_tree_add_string(tree, hf_smb_primary_domain,
2310                                 tvb, offset, dn_len, dn);
2311                         COUNT_BYTES(dn_len);
2312
2313                         /* server name, seen in w2k pro capture */
2314                         dn = get_unicode_or_ascii_string(tvb,
2315                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2316                                 &bc);
2317                         if (dn == NULL)
2318                                 goto endofcommand;
2319                         proto_tree_add_string(tree, hf_smb_server,
2320                                 tvb, offset, dn_len, dn);
2321                         COUNT_BYTES(dn_len);
2322
2323                 } else {
2324                         proto_item *blob_item;
2325
2326                         /* guid */
2327                         /* XXX - show it in the standard Microsoft format
2328                            for GUIDs? */
2329                         CHECK_BYTE_COUNT(16);
2330                         proto_tree_add_item(tree, hf_smb_server_guid,
2331                                 tvb, offset, 16, TRUE);
2332                         COUNT_BYTES(16);
2333
2334                         blob_item = proto_tree_add_item(
2335                                 tree, hf_smb_security_blob,
2336                                 tvb, offset, bc, TRUE);
2337
2338                         /* security blob */
2339                         /* 
2340                          * If Extended security and BCC == 16, then raw 
2341                          * NTLMSSP is in use. We need to save this info
2342                          */
2343  
2344                         if(bc){
2345                                 tvbuff_t *gssapi_tvb;
2346                                 proto_tree *gssapi_tree;
2347
2348                                 gssapi_tree = proto_item_add_subtree(
2349                                         blob_item, ett_smb_secblob);
2350
2351                                 gssapi_tvb = tvb_new_subset(
2352                                         tvb, offset, bc, bc);
2353
2354                                 call_dissector(
2355                                         gssapi_handle, gssapi_tvb, pinfo,
2356                                         gssapi_tree);
2357
2358                                 if (si->ct)
2359                                   si->ct->raw_ntlmssp = 0;
2360
2361                                 COUNT_BYTES(bc);
2362                         }
2363                         else { 
2364
2365                           /*
2366                            * There is no blob. We just have to make sure
2367                            * that subsequent routines know to call the 
2368                            * right things ...
2369                            */
2370
2371                           if (si->ct)
2372                             si->ct->raw_ntlmssp = 1;
2373
2374                         }
2375                 }
2376                 break;
2377         }
2378
2379         END_OF_SMB
2380
2381         return offset;
2382 }
2383
2384
2385 static int
2386 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2387 {
2388         smb_info_t *si = pinfo->private_data;
2389         int dn_len;
2390         const char *dn;
2391         guint8 wc;
2392         guint16 bc;
2393
2394         WORD_COUNT;
2395
2396         BYTE_COUNT;
2397
2398         /* buffer format */
2399         CHECK_BYTE_COUNT(1);
2400         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2401         COUNT_BYTES(1);
2402
2403         /* dir name */
2404         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2405                 FALSE, FALSE, &bc);
2406         if (dn == NULL)
2407                 goto endofcommand;
2408         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2409                 dn);
2410         COUNT_BYTES(dn_len);
2411
2412         if (check_col(pinfo->cinfo, COL_INFO)) {
2413                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2414         }
2415
2416         END_OF_SMB
2417
2418         return offset;
2419 }
2420
2421 static int
2422 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2423 {
2424         guint8 wc;
2425         guint16 bc;
2426
2427         WORD_COUNT;
2428
2429         BYTE_COUNT;
2430
2431         END_OF_SMB
2432
2433         return offset;
2434 }
2435
2436 static int
2437 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2438 {
2439         guint16 ec, bc;
2440         guint8 wc;
2441
2442         WORD_COUNT;
2443
2444         /* echo count */
2445         ec = tvb_get_letohs(tvb, offset);
2446         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2447         offset += 2;
2448
2449         BYTE_COUNT;
2450
2451         if (bc != 0) {
2452                 /* echo data */
2453                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2454                 COUNT_BYTES(bc);
2455         }
2456
2457         END_OF_SMB
2458
2459         return offset;
2460 }
2461
2462 static int
2463 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2464 {
2465         guint16 bc;
2466         guint8 wc;
2467
2468         WORD_COUNT;
2469
2470         /* echo sequence number */
2471         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2472         offset += 2;
2473
2474         BYTE_COUNT;
2475
2476         if (bc != 0) {
2477                 /* echo data */
2478                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2479                 COUNT_BYTES(bc);
2480         }
2481
2482         END_OF_SMB
2483
2484         return offset;
2485 }
2486
2487 static int
2488 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2489 {
2490         smb_info_t *si = pinfo->private_data;
2491         int an_len, pwlen;
2492         const char *an;
2493         guint8 wc;
2494         guint16 bc;
2495
2496         WORD_COUNT;
2497
2498         BYTE_COUNT;
2499
2500         /* buffer format */
2501         CHECK_BYTE_COUNT(1);
2502         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2503         COUNT_BYTES(1);
2504
2505         /* Path */
2506         an = get_unicode_or_ascii_string(tvb, &offset,
2507                 si->unicode, &an_len, FALSE, FALSE, &bc);
2508         if (an == NULL)
2509                 goto endofcommand;
2510         proto_tree_add_string(tree, hf_smb_path, tvb,
2511                 offset, an_len, an);
2512         COUNT_BYTES(an_len);
2513
2514         if (check_col(pinfo->cinfo, COL_INFO)) {
2515                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2516         }
2517
2518         /* buffer format */
2519         CHECK_BYTE_COUNT(1);
2520         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2521         COUNT_BYTES(1);
2522
2523         /* password, ANSI */
2524         /* XXX - what if this runs past bc? */
2525         pwlen = tvb_strsize(tvb, offset);
2526         CHECK_BYTE_COUNT(pwlen);
2527         proto_tree_add_item(tree, hf_smb_password,
2528                 tvb, offset, pwlen, TRUE);
2529         COUNT_BYTES(pwlen);
2530
2531         /* buffer format */
2532         CHECK_BYTE_COUNT(1);
2533         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2534         COUNT_BYTES(1);
2535
2536         /* Service */
2537         an = get_unicode_or_ascii_string(tvb, &offset,
2538                 si->unicode, &an_len, FALSE, FALSE, &bc);
2539         if (an == NULL)
2540                 goto endofcommand;
2541         proto_tree_add_string(tree, hf_smb_service, tvb,
2542                 offset, an_len, an);
2543         COUNT_BYTES(an_len);
2544
2545         END_OF_SMB
2546
2547         return offset;
2548 }
2549
2550 static int
2551 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2552 {
2553         guint8 wc;
2554         guint16 bc;
2555
2556         WORD_COUNT;
2557
2558         /* Maximum Buffer Size */
2559         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2560         offset += 2;
2561
2562         /* tid */
2563         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2564         offset += 2;
2565
2566         BYTE_COUNT;
2567
2568         END_OF_SMB
2569
2570         return offset;
2571 }
2572
2573
2574 static const true_false_string tfs_of_create = {
2575         "Create file if it does not exist",
2576         "Fail if file does not exist"
2577 };
2578 static const value_string of_open[] = {
2579         { 0,            "Fail if file exists"},
2580         { 1,            "Open file if it exists"},
2581         { 2,            "Truncate file if it exists"},
2582         {0, NULL}
2583 };
2584 static int
2585 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2586 {
2587         guint16 mask;
2588         proto_item *item = NULL;
2589         proto_tree *tree = NULL;
2590
2591         mask = tvb_get_letohs(tvb, offset);
2592
2593         if(parent_tree){
2594                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2595                         "Open Function: 0x%04x", mask);
2596                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2597         }
2598
2599         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2600                 tvb, offset, 2, mask);
2601         proto_tree_add_uint(tree, hf_smb_open_function_open,
2602                 tvb, offset, 2, mask);
2603
2604         offset += 2;
2605
2606         return offset;
2607 }
2608
2609
2610 static const true_false_string tfs_mf_file = {
2611         "Target must be a file",
2612         "Target needn't be a file"
2613 };
2614 static const true_false_string tfs_mf_dir = {
2615         "Target must be a directory",
2616         "Target needn't be a directory"
2617 };
2618 static const true_false_string tfs_mf_verify = {
2619         "MUST verify all writes",
2620         "Don't have to verify writes"
2621 };
2622 static int
2623 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2624 {
2625         guint16 mask;
2626         proto_item *item = NULL;
2627         proto_tree *tree = NULL;
2628
2629         mask = tvb_get_letohs(tvb, offset);
2630
2631         if(parent_tree){
2632                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2633                         "Flags: 0x%04x", mask);
2634                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2635         }
2636
2637         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2638                 tvb, offset, 2, mask);
2639         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2640                 tvb, offset, 2, mask);
2641         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2642                 tvb, offset, 2, mask);
2643
2644         offset += 2;
2645
2646         return offset;
2647 }
2648
2649 static const true_false_string tfs_cf_mode = {
2650         "ASCII",
2651         "Binary"
2652 };
2653 static const true_false_string tfs_cf_tree_copy = {
2654         "Copy is a tree copy",
2655         "Copy is a file copy"
2656 };
2657 static const true_false_string tfs_cf_ea_action = {
2658         "Fail copy",
2659         "Discard EAs"
2660 };
2661 static int
2662 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2663 {
2664         guint16 mask;
2665         proto_item *item = NULL;
2666         proto_tree *tree = NULL;
2667
2668         mask = tvb_get_letohs(tvb, offset);
2669
2670         if(parent_tree){
2671                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2672                         "Flags: 0x%04x", mask);
2673                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2674         }
2675
2676         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2677                 tvb, offset, 2, mask);
2678         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2679                 tvb, offset, 2, mask);
2680         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2681                 tvb, offset, 2, mask);
2682         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2683                 tvb, offset, 2, mask);
2684         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2685                 tvb, offset, 2, mask);
2686         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2687                 tvb, offset, 2, mask);
2688         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2689                 tvb, offset, 2, mask);
2690
2691         offset += 2;
2692
2693         return offset;
2694 }
2695
2696 static int
2697 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2698 {
2699         smb_info_t *si = pinfo->private_data;
2700         int fn_len;
2701         guint16 tid;
2702         guint16 bc;
2703         guint8 wc;
2704         const char *fn;
2705
2706         WORD_COUNT;
2707
2708         /* tid */
2709         tid = tvb_get_letohs(tvb, offset);
2710         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2711                 "TID (target): 0x%04x", tid);
2712         offset += 2;
2713
2714         /* open function */
2715         offset = dissect_open_function(tvb, tree, offset);
2716
2717         /* move flags */
2718         offset = dissect_move_flags(tvb, tree, offset);
2719
2720         BYTE_COUNT;
2721
2722         /* buffer format */
2723         CHECK_BYTE_COUNT(1);
2724         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2725         COUNT_BYTES(1);
2726
2727         /* file name */
2728         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2729                 FALSE, FALSE, &bc);
2730         if (fn == NULL)
2731                 goto endofcommand;
2732         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2733                 fn_len, fn, "Old File Name: %s", fn);
2734         COUNT_BYTES(fn_len);
2735
2736         if (check_col(pinfo->cinfo, COL_INFO)) {
2737                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2738         }
2739
2740         /* buffer format */
2741         CHECK_BYTE_COUNT(1);
2742         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2743         COUNT_BYTES(1);
2744
2745         /* file name */
2746         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2747                 FALSE, FALSE, &bc);
2748         if (fn == NULL)
2749                 goto endofcommand;
2750         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2751                 fn_len, fn, "New File Name: %s", fn);
2752         COUNT_BYTES(fn_len);
2753
2754         if (check_col(pinfo->cinfo, COL_INFO)) {
2755                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2756         }
2757
2758         END_OF_SMB
2759
2760         return offset;
2761 }
2762
2763 static int
2764 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2765 {
2766         smb_info_t *si = pinfo->private_data;
2767         int fn_len;
2768         guint16 tid;
2769         guint16 bc;
2770         guint8 wc;
2771         const char *fn;
2772
2773         WORD_COUNT;
2774
2775         /* tid */
2776         tid = tvb_get_letohs(tvb, offset);
2777         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2778                 "TID (target): 0x%04x", tid);
2779         offset += 2;
2780
2781         /* open function */
2782         offset = dissect_open_function(tvb, tree, offset);
2783
2784         /* copy flags */
2785         offset = dissect_copy_flags(tvb, tree, offset);
2786
2787         BYTE_COUNT;
2788
2789         /* buffer format */
2790         CHECK_BYTE_COUNT(1);
2791         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2792         COUNT_BYTES(1);
2793
2794         /* file name */
2795         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2796                 FALSE, FALSE, &bc);
2797         if (fn == NULL)
2798                 goto endofcommand;
2799         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2800                 fn_len, fn, "Source File Name: %s", fn);
2801         COUNT_BYTES(fn_len);
2802
2803         if (check_col(pinfo->cinfo, COL_INFO)) {
2804                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2805         }
2806
2807         /* buffer format */
2808         CHECK_BYTE_COUNT(1);
2809         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2810         COUNT_BYTES(1);
2811
2812         /* file name */
2813         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2814                 FALSE, FALSE, &bc);
2815         if (fn == NULL)
2816                 goto endofcommand;
2817         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2818                 fn_len, fn, "Destination File Name: %s", fn);
2819         COUNT_BYTES(fn_len);
2820
2821         if (check_col(pinfo->cinfo, COL_INFO)) {
2822                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2823         }
2824
2825         END_OF_SMB
2826
2827         return offset;
2828 }
2829
2830 static int
2831 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2832 {
2833         smb_info_t *si = pinfo->private_data;
2834         int fn_len;
2835         const char *fn;
2836         guint8 wc;
2837         guint16 bc;
2838
2839         WORD_COUNT;
2840
2841         /* # of files moved */
2842         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2843         offset += 2;
2844
2845         BYTE_COUNT;
2846
2847         /* buffer format */
2848         CHECK_BYTE_COUNT(1);
2849         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2850         COUNT_BYTES(1);
2851
2852         /* file name */
2853         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2854                 FALSE, FALSE, &bc);
2855         if (fn == NULL)
2856                 goto endofcommand;
2857         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2858                 fn);
2859         COUNT_BYTES(fn_len);
2860
2861         END_OF_SMB
2862
2863         return offset;
2864 }
2865
2866 static int
2867 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2868 {
2869         smb_info_t *si = pinfo->private_data;
2870         int fn_len;
2871         const char *fn;
2872         guint8 wc;
2873         guint16 bc;
2874
2875         WORD_COUNT;
2876
2877         /* desired access */
2878         offset = dissect_access(tvb, tree, offset, "Desired");
2879
2880         /* Search Attributes */
2881         offset = dissect_search_attributes(tvb, tree, offset);
2882
2883         BYTE_COUNT;
2884
2885         /* buffer format */
2886         CHECK_BYTE_COUNT(1);
2887         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2888         COUNT_BYTES(1);
2889
2890         /* file name */
2891         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2892                 FALSE, FALSE, &bc);
2893         if (fn == NULL)
2894                 goto endofcommand;
2895         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2896                 fn);
2897         COUNT_BYTES(fn_len);
2898
2899         if (check_col(pinfo->cinfo, COL_INFO)) {
2900                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2901         }
2902
2903         END_OF_SMB
2904
2905         return offset;
2906 }
2907
2908 void
2909 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2910     int len, guint16 fid)
2911 {
2912         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2913         if (check_col(pinfo->cinfo, COL_INFO))
2914                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2915 }
2916
2917 static int
2918 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2919 {
2920         guint8 wc;
2921         guint16 bc;
2922         guint16 fid;
2923
2924         WORD_COUNT;
2925
2926         /* fid */
2927         fid = tvb_get_letohs(tvb, offset);
2928         add_fid(tvb, pinfo, tree, offset, 2, fid);
2929         offset += 2;
2930
2931         /* File Attributes */
2932         offset = dissect_file_attributes(tvb, tree, offset, 2);
2933
2934         /* last write time */
2935         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2936
2937         /* File Size */
2938         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2939         offset += 4;
2940
2941         /* granted access */
2942         offset = dissect_access(tvb, tree, offset, "Granted");
2943
2944         BYTE_COUNT;
2945
2946         END_OF_SMB
2947
2948         return offset;
2949 }
2950
2951 static int
2952 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2953 {
2954         guint8 wc;
2955         guint16 bc;
2956         guint16 fid;
2957
2958         WORD_COUNT;
2959
2960         /* fid */
2961         fid = tvb_get_letohs(tvb, offset);
2962         add_fid(tvb, pinfo, tree, offset, 2, fid);
2963         offset += 2;
2964
2965         BYTE_COUNT;
2966
2967         END_OF_SMB
2968
2969         return offset;
2970 }
2971
2972 static int
2973 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2974 {
2975         smb_info_t *si = pinfo->private_data;
2976         int fn_len;
2977         const char *fn;
2978         guint8 wc;
2979         guint16 bc;
2980
2981         WORD_COUNT;
2982
2983         /* file attributes */
2984         offset = dissect_file_attributes(tvb, tree, offset, 2);
2985
2986         /* creation time */
2987         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2988
2989         BYTE_COUNT;
2990
2991         /* buffer format */
2992         CHECK_BYTE_COUNT(1);
2993         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2994         COUNT_BYTES(1);
2995
2996         /* File Name */
2997         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2998                 FALSE, FALSE, &bc);
2999         if (fn == NULL)
3000                 goto endofcommand;
3001         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3002                 fn);
3003         COUNT_BYTES(fn_len);
3004
3005         if (check_col(pinfo->cinfo, COL_INFO)) {
3006                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3007         }
3008
3009         END_OF_SMB
3010
3011         return offset;
3012 }
3013
3014 static int
3015 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3016 {
3017         guint8 wc;
3018         guint16 bc, fid;
3019
3020         WORD_COUNT;
3021
3022         /* fid */
3023         fid = tvb_get_letohs(tvb, offset);
3024         add_fid(tvb, pinfo, tree, offset, 2, fid);
3025         offset += 2;
3026
3027         /* last write time */
3028         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3029
3030         BYTE_COUNT;
3031
3032         END_OF_SMB
3033
3034         return offset;
3035 }
3036
3037 static int
3038 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3039 {
3040         smb_info_t *si = pinfo->private_data;
3041         int fn_len;
3042         const char *fn;
3043         guint8 wc;
3044         guint16 bc;
3045
3046         WORD_COUNT;
3047
3048         /* search attributes */
3049         offset = dissect_search_attributes(tvb, tree, offset);
3050
3051         BYTE_COUNT;
3052
3053         /* buffer format */
3054         CHECK_BYTE_COUNT(1);
3055         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3056         COUNT_BYTES(1);
3057
3058         /* file name */
3059         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3060                 FALSE, FALSE, &bc);
3061         if (fn == NULL)
3062                 goto endofcommand;
3063         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3064                 fn);
3065         COUNT_BYTES(fn_len);
3066
3067         if (check_col(pinfo->cinfo, COL_INFO)) {
3068                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3069         }
3070
3071         END_OF_SMB
3072
3073         return offset;
3074 }
3075
3076 static int
3077 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3078 {
3079         smb_info_t *si = pinfo->private_data;
3080         int fn_len;
3081         const char *fn;
3082         guint8 wc;
3083         guint16 bc;
3084
3085         WORD_COUNT;
3086
3087         /* search attributes */
3088         offset = dissect_search_attributes(tvb, tree, offset);
3089
3090         BYTE_COUNT;
3091
3092         /* buffer format */
3093         CHECK_BYTE_COUNT(1);
3094         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3095         COUNT_BYTES(1);
3096
3097         /* old file name */
3098         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3099                 FALSE, FALSE, &bc);
3100         if (fn == NULL)
3101                 goto endofcommand;
3102         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3103                 fn);
3104         COUNT_BYTES(fn_len);
3105
3106         if (check_col(pinfo->cinfo, COL_INFO)) {
3107                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3108         }
3109
3110         /* buffer format */
3111         CHECK_BYTE_COUNT(1);
3112         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3113         COUNT_BYTES(1);
3114
3115         /* file name */
3116         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3117                 FALSE, FALSE, &bc);
3118         if (fn == NULL)
3119                 goto endofcommand;
3120         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3121                 fn);
3122         COUNT_BYTES(fn_len);
3123
3124         if (check_col(pinfo->cinfo, COL_INFO)) {
3125                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3126         }
3127
3128         END_OF_SMB
3129
3130         return offset;
3131 }
3132
3133 static int
3134 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3135 {
3136         smb_info_t *si = pinfo->private_data;
3137         int fn_len;
3138         const char *fn;
3139         guint8 wc;
3140         guint16 bc;
3141
3142         WORD_COUNT;
3143
3144         /* search attributes */
3145         offset = dissect_search_attributes(tvb, tree, offset);
3146
3147         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3148         offset += 2;
3149
3150         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3151         offset += 4;
3152
3153         BYTE_COUNT;
3154
3155         /* buffer format */
3156         CHECK_BYTE_COUNT(1);
3157         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3158         COUNT_BYTES(1);
3159
3160         /* old file name */
3161         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3162                 FALSE, FALSE, &bc);
3163         if (fn == NULL)
3164                 goto endofcommand;
3165         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3166                 fn);
3167         COUNT_BYTES(fn_len);
3168
3169         if (check_col(pinfo->cinfo, COL_INFO)) {
3170                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3171         }
3172
3173         /* buffer format */
3174         CHECK_BYTE_COUNT(1);
3175         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3176         COUNT_BYTES(1);
3177
3178         /* file name */
3179         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3180                 FALSE, FALSE, &bc);
3181         if (fn == NULL)
3182                 goto endofcommand;
3183         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3184                 fn);
3185         COUNT_BYTES(fn_len);
3186
3187         if (check_col(pinfo->cinfo, COL_INFO)) {
3188                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3189         }
3190
3191         END_OF_SMB
3192
3193         return offset;
3194 }
3195
3196
3197 static int
3198 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3199 {
3200         smb_info_t *si = pinfo->private_data;
3201         guint16 bc;
3202         guint8 wc;
3203         const char *fn;
3204         int fn_len;
3205
3206         WORD_COUNT;
3207
3208         BYTE_COUNT;
3209
3210         /* Buffer Format */
3211         CHECK_BYTE_COUNT(1);
3212         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3213         COUNT_BYTES(1);
3214
3215         /* File Name */
3216         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3217                 FALSE, FALSE, &bc);
3218         if (fn == NULL)
3219                 goto endofcommand;
3220         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3221                 fn);
3222         COUNT_BYTES(fn_len);
3223
3224         if (check_col(pinfo->cinfo, COL_INFO)) {
3225                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3226         }
3227
3228         END_OF_SMB
3229
3230         return offset;
3231 }
3232
3233 static int
3234 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3235 {
3236         guint16 bc;
3237         guint8 wc;
3238
3239         WORD_COUNT;
3240
3241         /* File Attributes */
3242         offset = dissect_file_attributes(tvb, tree, offset, 2);
3243
3244         /* Last Write Time */
3245         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3246
3247         /* File Size */
3248         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3249         offset += 4;
3250
3251         /* 10 reserved bytes */
3252         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3253         offset += 10;
3254
3255         BYTE_COUNT;
3256
3257         END_OF_SMB
3258
3259         return offset;
3260 }
3261
3262 static int
3263 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3264 {
3265         smb_info_t *si = pinfo->private_data;
3266         int fn_len;
3267         const char *fn;
3268         guint8 wc;
3269         guint16 bc;
3270
3271         WORD_COUNT;
3272
3273         /* file attributes */
3274         offset = dissect_file_attributes(tvb, tree, offset, 2);
3275
3276         /* last write time */
3277         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3278
3279         /* 10 reserved bytes */
3280         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3281         offset += 10;
3282
3283         BYTE_COUNT;
3284
3285         /* buffer format */
3286         CHECK_BYTE_COUNT(1);
3287         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3288         COUNT_BYTES(1);
3289
3290         /* file name */
3291         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3292                 FALSE, FALSE, &bc);
3293         if (fn == NULL)
3294                 goto endofcommand;
3295         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3296                 fn);
3297         COUNT_BYTES(fn_len);
3298
3299         if (check_col(pinfo->cinfo, COL_INFO)) {
3300                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3301         }
3302
3303         END_OF_SMB
3304
3305         return offset;
3306 }
3307
3308 static int
3309 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3310 {
3311         guint8 wc;
3312         guint16 cnt=0, bc;
3313         guint32 ofs=0;
3314         smb_info_t *si;
3315         unsigned int fid;
3316
3317         WORD_COUNT;
3318
3319         /* fid */
3320         fid = tvb_get_letohs(tvb, offset);
3321         add_fid(tvb, pinfo, tree, offset, 2, fid);
3322         offset += 2;
3323         if (!pinfo->fd->flags.visited) {
3324                 /* remember the FID for the processing of the response */
3325                 si = (smb_info_t *)pinfo->private_data;
3326                 si->sip->extra_info=(void *)fid;
3327         }
3328
3329         /* read count */
3330         cnt = tvb_get_letohs(tvb, offset);
3331         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3332         offset += 2;
3333
3334         /* offset */
3335         ofs = tvb_get_letohl(tvb, offset);
3336         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3337         offset += 4;
3338
3339         if (check_col(pinfo->cinfo, COL_INFO))
3340                 col_append_fstr(pinfo->cinfo, COL_INFO,
3341                                 ", %u byte%s at offset %u", cnt,
3342                                 (cnt == 1) ? "" : "s", ofs);
3343
3344         /* remaining */
3345         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3346         offset += 2;
3347
3348         BYTE_COUNT;
3349
3350         END_OF_SMB
3351
3352         return offset;
3353 }
3354
3355 int
3356 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3357 {
3358         int tvblen;
3359
3360         if(bc>datalen){
3361                 /* We have some initial padding bytes. */
3362                 /* XXX - use the data offset here instead? */
3363                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3364                         TRUE);
3365                 offset += bc-datalen;
3366                 bc = datalen;
3367         }
3368         tvblen = tvb_length_remaining(tvb, offset);
3369         if(bc>tvblen){
3370                 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);
3371                 offset += tvblen;
3372         } else {
3373                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3374                 offset += bc;
3375         }
3376         return offset;
3377 }
3378
3379 static int
3380 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3381     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3382 {
3383         int tvblen;
3384         tvbuff_t *dcerpc_tvb;
3385
3386         if(bc>datalen){
3387                 /* We have some initial padding bytes. */
3388                 /* XXX - use the data offset here instead? */
3389                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3390                         TRUE);
3391                 offset += bc-datalen;
3392                 bc = datalen;
3393         }
3394         tvblen = tvb_length_remaining(tvb, offset);
3395         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3396         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3397         if(bc>tvblen)
3398                 offset += tvblen;
3399         else
3400                 offset += bc;
3401         return offset;
3402 }
3403
3404 /*
3405  * transporting DCERPC over SMB seems to be implemented in various
3406  * ways. We might just assume it can be done by an almost random
3407  * mix of Trans/Read/Write calls
3408  *
3409  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3410  * and let him sort them out
3411  */
3412 static int
3413 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3414     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3415     guint16 datalen, guint32 ofs, guint16 fid)
3416 {
3417         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3418
3419         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3420                 /* dcerpc call */
3421                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3422                     top_tree, offset, bc, datalen, fid);
3423         } else {
3424                 /* ordinary file data */
3425                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3426         }
3427 }
3428
3429 static int
3430 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3431 {
3432         guint16 cnt=0, bc;
3433         guint8 wc;
3434         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3435         int fid=0;
3436
3437         WORD_COUNT;
3438
3439         /* read count */
3440         cnt = tvb_get_letohs(tvb, offset);
3441         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3442         offset += 2;
3443
3444         /* 8 reserved bytes */
3445         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3446         offset += 8;
3447
3448         /* If we have seen the request, then print which FID this refers to */
3449         /* first check if we have seen the request */
3450         if(si->sip != NULL && si->sip->frame_req>0){
3451                 fid=(int)si->sip->extra_info;
3452                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3453         }
3454
3455         BYTE_COUNT;
3456
3457         /* buffer format */
3458         CHECK_BYTE_COUNT(1);
3459         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3460         COUNT_BYTES(1);
3461
3462         /* data len */
3463         CHECK_BYTE_COUNT(2);
3464         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3465         COUNT_BYTES(2);
3466
3467         /* file data, might be DCERPC on a pipe */
3468         if(bc){
3469                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3470                     top_tree, offset, bc, bc, 0, fid);
3471                 bc = 0;
3472         }
3473
3474         END_OF_SMB
3475
3476         return offset;
3477 }
3478
3479 static int
3480 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3481 {
3482         guint16 cnt, bc;
3483         guint8 wc;
3484
3485         WORD_COUNT;
3486
3487         /* read count */
3488         cnt = tvb_get_letohs(tvb, offset);
3489         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3490         offset += 2;
3491
3492         /* 8 reserved bytes */
3493         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3494         offset += 8;
3495
3496         BYTE_COUNT;
3497
3498         /* buffer format */
3499         CHECK_BYTE_COUNT(1);
3500         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3501         COUNT_BYTES(1);
3502
3503         /* data len */
3504         CHECK_BYTE_COUNT(2);
3505         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3506         COUNT_BYTES(2);
3507
3508         END_OF_SMB
3509
3510         return offset;
3511 }
3512
3513
3514 static int
3515 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3516 {
3517         guint32 ofs=0;
3518         guint16 cnt=0, bc, fid=0;
3519         guint8 wc;
3520
3521         WORD_COUNT;
3522
3523         /* fid */
3524         fid = tvb_get_letohs(tvb, offset);
3525         add_fid(tvb, pinfo, tree, offset, 2, fid);
3526         offset += 2;
3527
3528         /* write count */
3529         cnt = tvb_get_letohs(tvb, offset);
3530         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3531         offset += 2;
3532
3533         /* offset */
3534         ofs = tvb_get_letohl(tvb, offset);
3535         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3536         offset += 4;
3537
3538         if (check_col(pinfo->cinfo, COL_INFO))
3539                 col_append_fstr(pinfo->cinfo, COL_INFO,
3540                                 ", %u byte%s at offset %u", cnt,
3541                                 (cnt == 1) ? "" : "s", ofs);
3542
3543         /* remaining */
3544         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3545         offset += 2;
3546
3547         BYTE_COUNT;
3548
3549         /* buffer format */
3550         CHECK_BYTE_COUNT(1);
3551         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3552         COUNT_BYTES(1);
3553
3554         /* data len */
3555         CHECK_BYTE_COUNT(2);
3556         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3557         COUNT_BYTES(2);
3558
3559         /* file data, might be DCERPC on a pipe */
3560         if (bc != 0) {
3561                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3562                     top_tree, offset, bc, bc, ofs, fid);
3563                 bc = 0;
3564         }
3565
3566         END_OF_SMB
3567
3568         return offset;
3569 }
3570
3571 static int
3572 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3573 {
3574         guint8 wc;
3575         guint16 bc, cnt;
3576
3577         WORD_COUNT;
3578
3579         /* write count */
3580         cnt = tvb_get_letohs(tvb, offset);
3581         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3582         offset += 2;
3583
3584         if (check_col(pinfo->cinfo, COL_INFO))
3585                 col_append_fstr(pinfo->cinfo, COL_INFO,
3586                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3587
3588         BYTE_COUNT;
3589
3590         END_OF_SMB
3591
3592         return offset;
3593 }
3594
3595 static int
3596 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3597 {
3598         guint8 wc;
3599         guint16 bc, fid;
3600
3601         WORD_COUNT;
3602
3603         /* fid */
3604         fid = tvb_get_letohs(tvb, offset);
3605         add_fid(tvb, pinfo, tree, offset, 2, fid);
3606         offset += 2;
3607
3608         /* lock count */
3609         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3610         offset += 4;
3611
3612         /* offset */
3613         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3614         offset += 4;
3615
3616         BYTE_COUNT;
3617
3618         END_OF_SMB
3619
3620         return offset;
3621 }
3622
3623 static int
3624 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3625 {
3626         smb_info_t *si = pinfo->private_data;
3627         int fn_len;
3628         const char *fn;
3629         guint8 wc;
3630         guint16 bc;
3631
3632         WORD_COUNT;
3633
3634         /* 2 reserved bytes */
3635         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3636         offset += 2;
3637
3638         /* Creation time */
3639         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3640
3641         BYTE_COUNT;
3642
3643         /* buffer format */
3644         CHECK_BYTE_COUNT(1);
3645         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3646         COUNT_BYTES(1);
3647
3648         /* directory name */
3649         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3650                 FALSE, FALSE, &bc);
3651         if (fn == NULL)
3652                 goto endofcommand;
3653         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3654                 fn);
3655         COUNT_BYTES(fn_len);
3656
3657         if (check_col(pinfo->cinfo, COL_INFO)) {
3658                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3659         }
3660
3661         END_OF_SMB
3662
3663         return offset;
3664 }
3665
3666 static int
3667 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3668 {
3669         smb_info_t *si = pinfo->private_data;
3670         int fn_len;
3671         const char *fn;
3672         guint8 wc;
3673         guint16 bc, fid;
3674
3675         WORD_COUNT;
3676
3677         /* fid */
3678         fid = tvb_get_letohs(tvb, offset);
3679         add_fid(tvb, pinfo, tree, offset, 2, fid);
3680         offset += 2;
3681
3682         BYTE_COUNT;
3683
3684         /* buffer format */
3685         CHECK_BYTE_COUNT(1);
3686         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3687         COUNT_BYTES(1);
3688
3689         /* file name */
3690         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3691                 FALSE, FALSE, &bc);
3692         if (fn == NULL)
3693                 goto endofcommand;
3694         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3695                 fn);
3696         COUNT_BYTES(fn_len);
3697
3698         END_OF_SMB
3699
3700         return offset;
3701 }
3702
3703 static const value_string seek_mode_vals[] = {
3704         {0,     "From Start Of File"},
3705         {1,     "From Current Position"},
3706         {2,     "From End Of File"},
3707         {0,     NULL}
3708 };
3709
3710 static int
3711 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3712 {
3713         guint8 wc;
3714         guint16 bc, fid;
3715
3716         WORD_COUNT;
3717
3718         /* fid */
3719         fid = tvb_get_letohs(tvb, offset);
3720         add_fid(tvb, pinfo, tree, offset, 2, fid);
3721         offset += 2;
3722
3723         /* Seek Mode */
3724         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3725         offset += 2;
3726
3727         /* offset */
3728         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3729         offset += 4;
3730
3731         BYTE_COUNT;
3732
3733         END_OF_SMB
3734
3735         return offset;
3736 }
3737
3738 static int
3739 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3740 {
3741         guint8 wc;
3742         guint16 bc;
3743
3744         WORD_COUNT;
3745
3746         /* offset */
3747         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3748         offset += 4;
3749
3750         BYTE_COUNT;
3751
3752         END_OF_SMB
3753
3754         return offset;
3755 }
3756
3757 static int
3758 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3759 {
3760         guint8 wc;
3761         guint16 bc, fid;
3762
3763         WORD_COUNT;
3764
3765         /* fid */
3766         fid = tvb_get_letohs(tvb, offset);
3767         add_fid(tvb, pinfo, tree, offset, 2, fid);
3768         offset += 2;
3769
3770         /* create time */
3771         offset = dissect_smb_datetime(tvb, tree, offset,
3772                 hf_smb_create_time,
3773                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3774
3775         /* access time */
3776         offset = dissect_smb_datetime(tvb, tree, offset,
3777                 hf_smb_access_time,
3778                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3779
3780         /* last write time */
3781         offset = dissect_smb_datetime(tvb, tree, offset,
3782                 hf_smb_last_write_time,
3783                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3784
3785         BYTE_COUNT;
3786
3787         END_OF_SMB
3788
3789         return offset;
3790 }
3791
3792 static int
3793 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3794 {
3795         guint8 wc;
3796         guint16 bc;
3797
3798         WORD_COUNT;
3799
3800         /* create time */
3801         offset = dissect_smb_datetime(tvb, tree, offset,
3802                 hf_smb_create_time,
3803                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3804
3805         /* access time */
3806         offset = dissect_smb_datetime(tvb, tree, offset,
3807                 hf_smb_access_time,
3808                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3809
3810         /* last write time */
3811         offset = dissect_smb_datetime(tvb, tree, offset,
3812                 hf_smb_last_write_time,
3813                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3814
3815         /* data size */
3816         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3817         offset += 4;
3818
3819         /* allocation size */
3820         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3821         offset += 4;
3822
3823         /* File Attributes */
3824         offset = dissect_file_attributes(tvb, tree, offset, 2);
3825
3826         BYTE_COUNT;
3827
3828         END_OF_SMB
3829
3830         return offset;
3831 }
3832
3833 static int
3834 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3835 {
3836         guint8 wc;
3837         guint16 cnt=0;
3838         guint16 bc, fid;
3839
3840         WORD_COUNT;
3841
3842         /* fid */
3843         fid = tvb_get_letohs(tvb, offset);
3844         add_fid(tvb, pinfo, tree, offset, 2, fid);
3845         offset += 2;
3846
3847         /* write count */
3848         cnt = tvb_get_letohs(tvb, offset);
3849         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3850         offset += 2;
3851
3852         /* offset */
3853         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3854         offset += 4;
3855
3856         /* last write time */
3857         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3858
3859         if(wc==12){
3860                 /* 12 reserved bytes */
3861                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3862                 offset += 12;
3863         }
3864
3865         BYTE_COUNT;
3866
3867         /* 1 pad byte */
3868         CHECK_BYTE_COUNT(1);
3869         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3870         COUNT_BYTES(1);
3871
3872         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3873         bc = 0; /* XXX */
3874
3875         END_OF_SMB
3876
3877         return offset;
3878 }
3879
3880 static int
3881 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3882 {
3883         guint8 wc;
3884         guint16 bc;
3885
3886         WORD_COUNT;
3887
3888         /* write count */
3889         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3890         offset += 2;
3891
3892         BYTE_COUNT;
3893
3894         END_OF_SMB
3895
3896         return offset;
3897 }
3898
3899 static int
3900 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3901 {
3902         guint8 wc;
3903         guint16 bc, fid;
3904         guint32 to;
3905
3906         WORD_COUNT;
3907
3908         /* fid */
3909         fid = tvb_get_letohs(tvb, offset);
3910         add_fid(tvb, pinfo, tree, offset, 2, fid);
3911         offset += 2;
3912
3913         /* offset */
3914         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3915         offset += 4;
3916
3917         /* max count */
3918         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3919         offset += 2;
3920
3921         /* min count */
3922         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3923         offset += 2;
3924
3925         /* timeout */
3926         to = tvb_get_letohl(tvb, offset);
3927         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3928         offset += 4;
3929
3930         /* 2 reserved bytes */
3931         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3932         offset += 2;
3933
3934         if(wc==10){
3935                 /* high offset */
3936                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3937                 offset += 4;
3938         }
3939
3940         BYTE_COUNT;
3941
3942         END_OF_SMB
3943
3944         return offset;
3945 }
3946
3947 static int
3948 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3949 {
3950         guint8 wc;
3951         guint16 bc;
3952
3953         WORD_COUNT;
3954
3955         /* units */
3956         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3957         offset += 2;
3958
3959         /* bpu */
3960         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3961         offset += 2;
3962
3963         /* block size */
3964         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3965         offset += 2;
3966
3967         /* free units */
3968         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3969         offset += 2;
3970
3971         /* 2 reserved bytes */
3972         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3973         offset += 2;
3974
3975         BYTE_COUNT;
3976
3977         END_OF_SMB
3978
3979         return offset;
3980 }
3981
3982 static int
3983 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3984 {
3985         guint8 wc;
3986         guint16 bc, fid;
3987
3988         WORD_COUNT;
3989
3990         /* fid */
3991         fid = tvb_get_letohs(tvb, offset);
3992         add_fid(tvb, pinfo, tree, offset, 2, fid);
3993         offset += 2;
3994
3995         /* offset */
3996         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3997         offset += 4;
3998
3999         /* max count */
4000         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4001         offset += 2;
4002
4003         /* min count */
4004         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4005         offset += 2;
4006
4007         /* 6 reserved bytes */
4008         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4009         offset += 6;
4010
4011         BYTE_COUNT;
4012
4013         END_OF_SMB
4014
4015         return offset;
4016 }
4017
4018 static int
4019 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4020 {
4021         guint16 datalen=0, bc;
4022         guint8 wc;
4023
4024         WORD_COUNT;
4025
4026         /* offset */
4027         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4028         offset += 4;
4029
4030         /* count */
4031         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4032         offset += 2;
4033
4034         /* 2 reserved bytes */
4035         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4036         offset += 2;
4037
4038         /* data compaction mode */
4039         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4040         offset += 2;
4041
4042         /* 2 reserved bytes */
4043         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4044         offset += 2;
4045
4046         /* data len */
4047         datalen = tvb_get_letohs(tvb, offset);
4048         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4049         offset += 2;
4050
4051         /* data offset */
4052         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4053         offset += 2;
4054
4055         BYTE_COUNT;
4056
4057         /* file data */
4058         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4059         bc = 0;
4060
4061         END_OF_SMB
4062
4063         return offset;
4064 }
4065
4066
4067 static const true_false_string tfs_write_mode_write_through = {
4068         "WRITE THROUGH requested",
4069         "Write through not requested"
4070 };
4071 static const true_false_string tfs_write_mode_return_remaining = {
4072         "RETURN REMAINING (pipe/dev) requested",
4073         "DON'T return remaining (pipe/dev)"
4074 };
4075 static const true_false_string tfs_write_mode_raw = {
4076         "Use WriteRawNamedPipe (pipe)",
4077         "DON'T use WriteRawNamedPipe (pipe)"
4078 };
4079 static const true_false_string tfs_write_mode_message_start = {
4080         "This is the START of a MESSAGE (pipe)",
4081         "This is NOT the start of a message (pipe)"
4082 };
4083 static const true_false_string tfs_write_mode_connectionless = {
4084         "CONNECTIONLESS mode requested",
4085         "Connectionless mode NOT requested"
4086 };
4087
4088 #define WRITE_MODE_CONNECTIONLESS       0x0080
4089 #define WRITE_MODE_MESSAGE_START        0x0008
4090 #define WRITE_MODE_RAW                  0x0004
4091 #define WRITE_MODE_RETURN_REMAINING     0x0002
4092 #define WRITE_MODE_WRITE_THROUGH        0x0001
4093
4094 static int
4095 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4096 {
4097         guint16 mask;
4098         proto_item *item = NULL;
4099         proto_tree *tree = NULL;
4100
4101         mask = tvb_get_letohs(tvb, offset);
4102
4103         if(parent_tree){
4104                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4105                         "Write Mode: 0x%04x", mask);
4106                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4107         }
4108
4109         if(bm&WRITE_MODE_CONNECTIONLESS){
4110                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4111                         tvb, offset, 2, mask);
4112         }
4113         if(bm&WRITE_MODE_MESSAGE_START){
4114                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4115                         tvb, offset, 2, mask);
4116         }
4117         if(bm&WRITE_MODE_RAW){
4118                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4119                         tvb, offset, 2, mask);
4120         }
4121         if(bm&WRITE_MODE_RETURN_REMAINING){
4122                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4123                         tvb, offset, 2, mask);
4124         }
4125         if(bm&WRITE_MODE_WRITE_THROUGH){
4126                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4127                         tvb, offset, 2, mask);
4128         }
4129
4130         offset += 2;
4131         return offset;
4132 }
4133
4134 static int
4135 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4136 {
4137         guint32 to;
4138         guint16 datalen=0, bc, fid;
4139         guint8 wc;
4140
4141         WORD_COUNT;
4142
4143         /* fid */
4144         fid = tvb_get_letohs(tvb, offset);
4145         add_fid(tvb, pinfo, tree, offset, 2, fid);
4146         offset += 2;
4147
4148         /* total data length */
4149         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4150         offset += 2;
4151
4152         /* 2 reserved bytes */
4153         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4154         offset += 2;
4155
4156         /* offset */
4157         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4158         offset += 4;
4159
4160         /* timeout */
4161         to = tvb_get_letohl(tvb, offset);
4162         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4163         offset += 4;
4164
4165         /* mode */
4166         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4167
4168         /* 4 reserved bytes */
4169         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4170         offset += 4;
4171
4172         /* data len */
4173         datalen = tvb_get_letohs(tvb, offset);
4174         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4175         offset += 2;
4176
4177         /* data offset */
4178         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4179         offset += 2;
4180
4181         BYTE_COUNT;
4182
4183         /* file data */
4184         /* XXX - use the data offset to determine where the data starts? */
4185         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4186         bc = 0;
4187
4188         END_OF_SMB
4189
4190         return offset;
4191 }
4192
4193 static int
4194 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4195 {
4196         guint8 wc;
4197         guint16 bc;
4198
4199         WORD_COUNT;
4200
4201         /* remaining */
4202         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4203         offset += 2;
4204
4205         BYTE_COUNT;
4206
4207         END_OF_SMB
4208
4209         return offset;
4210 }
4211
4212 static int
4213 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4214 {
4215         guint32 to;
4216         guint16 datalen=0, bc, fid;
4217         guint8 wc;
4218
4219         WORD_COUNT;
4220
4221         /* fid */
4222         fid = tvb_get_letohs(tvb, offset);
4223         add_fid(tvb, pinfo, tree, offset, 2, fid);
4224         offset += 2;
4225
4226         /* total data length */
4227         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4228         offset += 2;
4229
4230         /* 2 reserved bytes */
4231         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4232         offset += 2;
4233
4234         /* offset */
4235         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4236         offset += 4;
4237
4238         /* timeout */
4239         to = tvb_get_letohl(tvb, offset);
4240         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4241         offset += 4;
4242
4243         /* mode */
4244         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4245
4246         /* request mask */
4247         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4248         offset += 4;
4249
4250         /* data len */
4251         datalen = tvb_get_letohs(tvb, offset);
4252         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4253         offset += 2;
4254
4255         /* data offset */
4256         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4257         offset += 2;
4258
4259         BYTE_COUNT;
4260
4261         /* file data */
4262         /* XXX - use the data offset to determine where the data starts? */
4263         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4264         bc = 0;
4265
4266         END_OF_SMB
4267
4268         return offset;
4269 }
4270
4271 static int
4272 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4273 {
4274         guint8 wc;
4275         guint16 bc;
4276
4277         WORD_COUNT;
4278
4279         /* response mask */
4280         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4281         offset += 4;
4282
4283         BYTE_COUNT;
4284
4285         END_OF_SMB
4286
4287         return offset;
4288 }
4289
4290 static int
4291 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4292 {
4293         guint8 wc;
4294         guint16 bc;
4295
4296         WORD_COUNT;
4297
4298         /* sid */
4299         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4300         offset += 2;
4301
4302         BYTE_COUNT;
4303
4304         END_OF_SMB
4305
4306         return offset;
4307 }
4308
4309 static int
4310 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4311     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4312     gboolean has_find_id)
4313 {
4314         proto_item *item = NULL;
4315         proto_tree *tree = NULL;
4316         smb_info_t *si = pinfo->private_data;
4317         int fn_len;
4318         const char *fn;
4319         char fname[11+1];
4320
4321         if(parent_tree){
4322                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4323                         "Resume Key");
4324                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4325         }
4326
4327         /* reserved byte */
4328         CHECK_BYTE_COUNT_SUBR(1);
4329         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4330         COUNT_BYTES_SUBR(1);
4331
4332         /* file name */
4333         fn_len = 11;
4334         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4335                 TRUE, TRUE, bcp);
4336         CHECK_STRING_SUBR(fn);
4337         /* ensure that it's null-terminated */
4338         strncpy(fname, fn, 11);
4339         fname[11] = '\0';
4340         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4341                 fname);
4342         COUNT_BYTES_SUBR(fn_len);
4343
4344         if (has_find_id) {
4345                 CHECK_BYTE_COUNT_SUBR(1);
4346                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4347                 COUNT_BYTES_SUBR(1);
4348
4349                 /* server cookie */
4350                 CHECK_BYTE_COUNT_SUBR(4);
4351                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4352                 COUNT_BYTES_SUBR(4);
4353         } else {
4354                 /* server cookie */
4355                 CHECK_BYTE_COUNT_SUBR(5);
4356                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4357                 COUNT_BYTES_SUBR(5);
4358         }
4359
4360         /* client cookie */
4361         CHECK_BYTE_COUNT_SUBR(4);
4362         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4363         COUNT_BYTES_SUBR(4);
4364
4365         *trunc = FALSE;
4366         return offset;
4367 }
4368
4369 static int
4370 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4371     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4372     gboolean has_find_id)
4373 {
4374         proto_item *item = NULL;
4375         proto_tree *tree = NULL;
4376         smb_info_t *si = pinfo->private_data;
4377         int fn_len;
4378         const char *fn;
4379         char fname[13+1];
4380
4381         if(parent_tree){
4382                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4383                         "Directory Information");
4384                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4385         }
4386
4387         /* resume key */
4388         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4389             trunc, has_find_id);
4390         if (*trunc)
4391                 return offset;
4392
4393         /* File Attributes */
4394         CHECK_BYTE_COUNT_SUBR(1);
4395         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4396         *bcp -= 1;
4397
4398         /* last write time */
4399         CHECK_BYTE_COUNT_SUBR(4);
4400         offset = dissect_smb_datetime(tvb, tree, offset,
4401                 hf_smb_last_write_time,
4402                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4403                 TRUE);
4404         *bcp -= 4;
4405
4406         /* File Size */
4407         CHECK_BYTE_COUNT_SUBR(4);
4408         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4409         COUNT_BYTES_SUBR(4);
4410
4411         /* file name */
4412         fn_len = 13;
4413         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4414                 TRUE, TRUE, bcp);
4415         CHECK_STRING_SUBR(fn);
4416         /* ensure that it's null-terminated */
4417         strncpy(fname, fn, 13);
4418         fname[13] = '\0';
4419         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4420                 fname);
4421         COUNT_BYTES_SUBR(fn_len);
4422
4423         *trunc = FALSE;
4424         return offset;
4425 }
4426
4427
4428 static int
4429 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4430     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4431     gboolean has_find_id)
4432 {
4433         smb_info_t *si = pinfo->private_data;
4434         int fn_len;
4435         const char *fn;
4436         guint16 rkl;
4437         guint8 wc;
4438         guint16 bc;
4439         gboolean trunc;
4440
4441         WORD_COUNT;
4442
4443         /* max count */
4444         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4445         offset += 2;
4446
4447         /* Search Attributes */
4448         offset = dissect_search_attributes(tvb, tree, offset);
4449
4450         BYTE_COUNT;
4451
4452         /* buffer format */
4453         CHECK_BYTE_COUNT(1);
4454         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4455         COUNT_BYTES(1);
4456
4457         /* file name */
4458         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4459                 TRUE, FALSE, &bc);
4460         if (fn == NULL)
4461                 goto endofcommand;
4462         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4463                 fn);
4464         COUNT_BYTES(fn_len);
4465
4466         if (check_col(pinfo->cinfo, COL_INFO)) {
4467                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4468         }
4469
4470         /* buffer format */
4471         CHECK_BYTE_COUNT(1);
4472         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4473         COUNT_BYTES(1);
4474
4475         /* resume key length */
4476         CHECK_BYTE_COUNT(2);
4477         rkl = tvb_get_letohs(tvb, offset);
4478         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4479         COUNT_BYTES(2);
4480
4481         /* resume key */
4482         if(rkl){
4483                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4484                     &bc, &trunc, has_find_id);
4485                 if (trunc)
4486                         goto endofcommand;
4487         }
4488
4489         END_OF_SMB
4490
4491         return offset;
4492 }
4493
4494 static int
4495 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4496     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4497 {
4498         return dissect_search_find_request(tvb, pinfo, tree, offset,
4499             smb_tree, FALSE);
4500 }
4501
4502 static int
4503 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4504     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4505 {
4506         return dissect_search_find_request(tvb, pinfo, tree, offset,
4507             smb_tree, TRUE);
4508 }
4509
4510 static int
4511 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4512     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4513 {
4514         return dissect_search_find_request(tvb, pinfo, tree, offset,
4515             smb_tree, TRUE);
4516 }
4517
4518 static int
4519 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4520     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4521     gboolean has_find_id)
4522 {
4523         guint16 count=0;
4524         guint8 wc;
4525         guint16 bc;
4526         gboolean trunc;
4527
4528         WORD_COUNT;
4529
4530         /* count */
4531         count = tvb_get_letohs(tvb, offset);
4532         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4533         offset += 2;
4534
4535         BYTE_COUNT;
4536
4537         /* buffer format */
4538         CHECK_BYTE_COUNT(1);
4539         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4540         COUNT_BYTES(1);
4541
4542         /* data len */
4543         CHECK_BYTE_COUNT(2);
4544         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4545         COUNT_BYTES(2);
4546
4547         while(count--){
4548                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4549                     &bc, &trunc, has_find_id);
4550                 if (trunc)
4551                         goto endofcommand;
4552         }
4553
4554         END_OF_SMB
4555
4556         return offset;
4557 }
4558
4559 static int
4560 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4561 {
4562         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4563             FALSE);
4564 }
4565
4566 static int
4567 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4568 {
4569         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4570             TRUE);
4571 }
4572
4573 static int
4574 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4575     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4576 {
4577         guint8 wc;
4578         guint16 bc;
4579         guint16 data_len;
4580
4581         WORD_COUNT;
4582
4583         /* reserved */
4584         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4585         offset += 2;
4586
4587         BYTE_COUNT;
4588
4589         /* buffer format */
4590         CHECK_BYTE_COUNT(1);
4591         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4592         COUNT_BYTES(1);
4593
4594         /* data len */
4595         CHECK_BYTE_COUNT(2);
4596         data_len = tvb_get_ntohs(tvb, offset);
4597         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4598         COUNT_BYTES(2);
4599
4600         if (data_len != 0) {
4601                 CHECK_BYTE_COUNT(data_len);
4602                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4603                     data_len, TRUE);
4604                 COUNT_BYTES(data_len);
4605         }
4606
4607         END_OF_SMB
4608
4609         return offset;
4610 }
4611
4612 static const value_string locking_ol_vals[] = {
4613         {0,     "Client is not holding oplock on this file"},
4614         {1,     "Level 2 oplock currently held by client"},
4615         {0, NULL}
4616 };
4617
4618 static const true_false_string tfs_lock_type_large = {
4619         "Large file locking format requested",
4620         "Large file locking format not requested"
4621 };
4622 static const true_false_string tfs_lock_type_cancel = {
4623         "Cancel outstanding lock request",
4624         "Don't cancel outstanding lock request"
4625 };
4626 static const true_false_string tfs_lock_type_change = {
4627         "Change lock type",
4628         "Don't change lock type"
4629 };
4630 static const true_false_string tfs_lock_type_oplock = {
4631         "This is an oplock break notification/response",
4632         "This is not an oplock break notification/response"
4633 };
4634 static const true_false_string tfs_lock_type_shared = {
4635         "This is a shared lock",
4636         "This is an exclusive lock"
4637 };
4638 static int
4639 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4640 {
4641         guint8  wc, cmd=0xff, lt=0;
4642         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4643         guint32 to;
4644         proto_item *litem = NULL;
4645         proto_tree *ltree = NULL;
4646         proto_item *it = NULL;
4647         proto_tree *tr = NULL;
4648         int old_offset = offset;
4649
4650         WORD_COUNT;
4651
4652         /* next smb command */
4653         cmd = tvb_get_guint8(tvb, offset);
4654         if(cmd!=0xff){
4655                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4656         } else {
4657                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4658         }
4659         offset += 1;
4660
4661         /* reserved byte */
4662         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4663         offset += 1;
4664
4665         /* andxoffset */
4666         andxoffset = tvb_get_letohs(tvb, offset);
4667         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4668         offset += 2;
4669
4670         /* fid */
4671         fid = tvb_get_letohs(tvb, offset);
4672         add_fid(tvb, pinfo, tree, offset, 2, fid);
4673         offset += 2;
4674
4675         /* lock type */
4676         lt = tvb_get_guint8(tvb, offset);
4677         if(tree){
4678                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4679                         "Lock Type: 0x%02x", lt);
4680                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4681         }
4682         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4683                 tvb, offset, 1, lt);
4684         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4685                 tvb, offset, 1, lt);
4686         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4687                 tvb, offset, 1, lt);
4688         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4689                 tvb, offset, 1, lt);
4690         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4691                 tvb, offset, 1, lt);
4692         offset += 1;
4693
4694         /* oplock level */
4695         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4696         offset += 1;
4697
4698         /* timeout */
4699         to = tvb_get_letohl(tvb, offset);
4700         if (to == 0)
4701                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4702         else if (to == 0xffffffff)
4703                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4704         else
4705                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4706         offset += 4;
4707
4708         /* number of unlocks */
4709         un = tvb_get_letohs(tvb, offset);
4710         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4711         offset += 2;
4712
4713         /* number of locks */
4714         ln = tvb_get_letohs(tvb, offset);
4715         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4716         offset += 2;
4717
4718         BYTE_COUNT;
4719
4720         /* unlocks */
4721         if(un){
4722                 old_offset = offset;
4723
4724                 it = proto_tree_add_text(tree, tvb, offset, -1,
4725                         "Unlocks");
4726                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4727                 while(un--){
4728                         proto_item *litem = NULL;
4729                         proto_tree *ltree = NULL;
4730                         if(lt&0x10){
4731                                 /* large lock format */
4732                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4733                                         "Unlock");
4734                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4735
4736                                 /* PID */
4737                                 CHECK_BYTE_COUNT(2);
4738                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4739                                 COUNT_BYTES(2);
4740
4741                                 /* 2 reserved bytes */
4742                                 CHECK_BYTE_COUNT(2);
4743                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4744                                 COUNT_BYTES(2);
4745
4746                                 /* offset */
4747                                 CHECK_BYTE_COUNT(8);
4748                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4749                                 COUNT_BYTES(8);
4750
4751                                 /* length */
4752                                 CHECK_BYTE_COUNT(8);
4753                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4754                                 COUNT_BYTES(8);
4755                         } else {
4756                                 /* normal lock format */
4757                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4758                                         "Unlock");
4759                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4760
4761                                 /* PID */
4762                                 CHECK_BYTE_COUNT(2);
4763                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4764                                 COUNT_BYTES(2);
4765
4766                                 /* offset */
4767                                 CHECK_BYTE_COUNT(4);
4768                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4769                                 COUNT_BYTES(4);
4770
4771                                 /* lock count */
4772                                 CHECK_BYTE_COUNT(4);
4773                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4774                                 COUNT_BYTES(4);
4775                         }
4776                 }
4777                 proto_item_set_len(it, offset-old_offset);
4778                 it = NULL;
4779         }
4780
4781         /* locks */
4782         if(ln){
4783                 old_offset = offset;
4784
4785                 it = proto_tree_add_text(tree, tvb, offset, -1,
4786                         "Locks");
4787                 tr = proto_item_add_subtree(it, ett_smb_locks);
4788                 while(ln--){
4789                         proto_item *litem = NULL;
4790                         proto_tree *ltree = NULL;
4791                         if(lt&0x10){
4792                                 /* large lock format */
4793                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4794                                         "Lock");
4795                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4796
4797                                 /* PID */
4798                                 CHECK_BYTE_COUNT(2);
4799                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4800                                 COUNT_BYTES(2);
4801
4802                                 /* 2 reserved bytes */
4803                                 CHECK_BYTE_COUNT(2);
4804                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4805                                 COUNT_BYTES(2);
4806
4807                                 /* offset */
4808                                 CHECK_BYTE_COUNT(8);
4809                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4810                                 COUNT_BYTES(8);
4811
4812                                 /* length */
4813                                 CHECK_BYTE_COUNT(8);
4814                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4815                                 COUNT_BYTES(8);
4816                         } else {
4817                                 /* normal lock format */
4818                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4819                                         "Unlock");
4820                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4821
4822                                 /* PID */
4823                                 CHECK_BYTE_COUNT(2);
4824                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4825                                 COUNT_BYTES(2);
4826
4827                                 /* offset */
4828                                 CHECK_BYTE_COUNT(4);
4829                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4830                                 COUNT_BYTES(4);
4831
4832                                 /* lock count */
4833                                 CHECK_BYTE_COUNT(4);
4834                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4835                                 COUNT_BYTES(4);
4836                         }
4837                 }
4838                 proto_item_set_len(it, offset-old_offset);
4839                 it = NULL;
4840         }
4841
4842         END_OF_SMB
4843
4844         if (it != NULL) {
4845                 /*
4846                  * We ran out of byte count in the middle of dissecting
4847                  * the locks or the unlocks; set the site of the item
4848                  * we were dissecting.
4849                  */
4850                 proto_item_set_len(it, offset-old_offset);
4851         }
4852
4853         /* call AndXCommand (if there are any) */
4854         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4855
4856         return offset;
4857 }
4858
4859 static int
4860 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4861 {
4862         guint8  wc, cmd=0xff;
4863         guint16 andxoffset=0;
4864         guint16 bc;
4865
4866         WORD_COUNT;
4867
4868         /* next smb command */
4869         cmd = tvb_get_guint8(tvb, offset);
4870         if(cmd!=0xff){
4871                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4872         } else {
4873                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4874         }
4875         offset += 1;
4876
4877         /* reserved byte */
4878         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4879         offset += 1;
4880
4881         /* andxoffset */
4882         andxoffset = tvb_get_letohs(tvb, offset);
4883         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4884         offset += 2;
4885
4886         BYTE_COUNT;
4887
4888         END_OF_SMB
4889
4890         /* call AndXCommand (if there are any) */
4891         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4892
4893         return offset;
4894 }
4895
4896
4897 static const value_string oa_open_vals[] = {
4898         { 0,            "No action taken?"},
4899         { 1,            "The file existed and was opened"},
4900         { 2,            "The file did not exist but was created"},
4901         { 3,            "The file existed and was truncated"},
4902         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4903         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4904         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4905         {0,     NULL}
4906 };
4907 static const true_false_string tfs_oa_lock = {
4908         "File is currently opened only by this user",
4909         "File is opened by another user (or mode not supported by server)"
4910 };
4911 static int
4912 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4913 {
4914         guint16 mask;
4915         proto_item *item = NULL;
4916         proto_tree *tree = NULL;
4917
4918         mask = tvb_get_letohs(tvb, offset);
4919
4920         if(parent_tree){
4921                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4922                         "Action: 0x%04x", mask);
4923                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4924         }
4925
4926         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4927                 tvb, offset, 2, mask);
4928         proto_tree_add_uint(tree, hf_smb_open_action_open,
4929                 tvb, offset, 2, mask);
4930
4931         offset += 2;
4932
4933         return offset;
4934 }
4935
4936 static const true_false_string tfs_open_flags_add_info = {
4937         "Additional information requested",
4938         "Additional information not requested"
4939 };
4940 static const true_false_string tfs_open_flags_ex_oplock = {
4941         "Exclusive oplock requested",
4942         "Exclusive oplock not requested"
4943 };
4944 static const true_false_string tfs_open_flags_batch_oplock = {
4945         "Batch oplock requested",
4946         "Batch oplock not requested"
4947 };
4948 static const true_false_string tfs_open_flags_ealen = {
4949         "Total length of EAs requested",
4950         "Total length of EAs not requested"
4951 };
4952 static int
4953 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4954 {
4955         guint16 mask;
4956         proto_item *item = NULL;
4957         proto_tree *tree = NULL;
4958
4959         mask = tvb_get_letohs(tvb, offset);
4960
4961         if(parent_tree){
4962                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4963                         "Flags: 0x%04x", mask);
4964                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4965         }
4966
4967         if(bm&0x0001){
4968                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4969                         tvb, offset, 2, mask);
4970         }
4971         if(bm&0x0002){
4972                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4973                         tvb, offset, 2, mask);
4974         }
4975         if(bm&0x0004){
4976                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4977                         tvb, offset, 2, mask);
4978         }
4979         if(bm&0x0008){
4980                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4981                         tvb, offset, 2, mask);
4982         }
4983
4984         offset += 2;
4985
4986         return offset;
4987 }
4988
4989 static const value_string filetype_vals[] = {
4990         { 0,            "Disk file or directory"},
4991         { 1,            "Named pipe in byte mode"},
4992         { 2,            "Named pipe in message mode"},
4993         { 3,            "Spooled printer"},
4994         {0, NULL}
4995 };
4996 static int
4997 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4998 {
4999         guint8  wc, cmd=0xff;
5000         guint16 andxoffset=0, bc;
5001         smb_info_t *si = pinfo->private_data;
5002         int fn_len;
5003         const char *fn;
5004
5005         WORD_COUNT;
5006
5007         /* next smb command */
5008         cmd = tvb_get_guint8(tvb, offset);
5009         if(cmd!=0xff){
5010                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5011         } else {
5012                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5013         }
5014         offset += 1;
5015
5016         /* reserved byte */
5017         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5018         offset += 1;
5019
5020         /* andxoffset */
5021         andxoffset = tvb_get_letohs(tvb, offset);
5022         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5023         offset += 2;
5024
5025         /* open flags */
5026         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5027
5028         /* desired access */
5029         offset = dissect_access(tvb, tree, offset, "Desired");
5030
5031         /* Search Attributes */
5032         offset = dissect_search_attributes(tvb, tree, offset);
5033
5034         /* File Attributes */
5035         offset = dissect_file_attributes(tvb, tree, offset, 2);
5036
5037         /* creation time */
5038         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5039
5040         /* open function */
5041         offset = dissect_open_function(tvb, tree, offset);
5042
5043         /* allocation size */
5044         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5045         offset += 4;
5046
5047         /* 8 reserved bytes */
5048         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5049         offset += 8;
5050
5051         BYTE_COUNT;
5052
5053         /* file name */
5054         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5055                 FALSE, FALSE, &bc);
5056         if (fn == NULL)
5057                 goto endofcommand;
5058         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5059                 fn);
5060         COUNT_BYTES(fn_len);
5061
5062         if (check_col(pinfo->cinfo, COL_INFO)) {
5063                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5064         }
5065
5066         END_OF_SMB
5067
5068         /* call AndXCommand (if there are any) */
5069         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5070
5071         return offset;
5072 }
5073
5074 static const true_false_string tfs_ipc_state_nonblocking = {
5075         "Reads/writes return immediately if no data available",
5076         "Reads/writes block if no data available"
5077 };
5078 static const value_string ipc_state_endpoint_vals[] = {
5079         { 0,            "Consumer end of pipe"},
5080         { 1,            "Server end of pipe"},
5081         {0,     NULL}
5082 };
5083 static const value_string ipc_state_pipe_type_vals[] = {
5084         { 0,            "Byte stream pipe"},
5085         { 1,            "Message pipe"},
5086         {0,     NULL}
5087 };
5088 static const value_string ipc_state_read_mode_vals[] = {
5089         { 0,            "Read pipe as a byte stream"},
5090         { 1,            "Read messages from pipe"},
5091         {0,     NULL}
5092 };
5093
5094 int
5095 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5096     gboolean setstate)
5097 {
5098         guint16 mask;
5099         proto_item *item = NULL;
5100         proto_tree *tree = NULL;
5101
5102         mask = tvb_get_letohs(tvb, offset);
5103
5104         if(parent_tree){
5105                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5106                         "IPC State: 0x%04x", mask);
5107                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5108         }
5109
5110         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5111                 tvb, offset, 2, mask);
5112         if (!setstate) {
5113                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5114                         tvb, offset, 2, mask);
5115                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5116                         tvb, offset, 2, mask);
5117         }
5118         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5119                 tvb, offset, 2, mask);
5120         if (!setstate) {
5121                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5122                         tvb, offset, 2, mask);
5123         }
5124
5125         offset += 2;
5126
5127         return offset;
5128 }
5129
5130 static int
5131 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5132 {
5133         guint8  wc, cmd=0xff;
5134         guint16 andxoffset=0, bc;
5135         guint16 fid;
5136
5137         WORD_COUNT;
5138
5139         /* next smb command */
5140         cmd = tvb_get_guint8(tvb, offset);
5141         if(cmd!=0xff){
5142                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5143         } else {
5144                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5145         }
5146         offset += 1;
5147
5148         /* reserved byte */
5149         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5150         offset += 1;
5151
5152         /* andxoffset */
5153         andxoffset = tvb_get_letohs(tvb, offset);
5154         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5155         offset += 2;
5156
5157         /* fid */
5158         fid = tvb_get_letohs(tvb, offset);
5159         add_fid(tvb, pinfo, tree, offset, 2, fid);
5160         offset += 2;
5161
5162         /* File Attributes */
5163         offset = dissect_file_attributes(tvb, tree, offset, 2);
5164
5165         /* last write time */
5166         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5167
5168         /* File Size */
5169         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5170         offset += 4;
5171
5172         /* granted access */
5173         offset = dissect_access(tvb, tree, offset, "Granted");
5174
5175         /* File Type */
5176         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5177         offset += 2;
5178
5179         /* IPC State */
5180         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5181
5182         /* open_action */
5183         offset = dissect_open_action(tvb, tree, offset);
5184
5185         /* server fid */
5186         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5187         offset += 4;
5188
5189         /* 2 reserved bytes */
5190         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5191         offset += 2;
5192
5193         BYTE_COUNT;
5194
5195         END_OF_SMB
5196
5197         /* call AndXCommand (if there are any) */
5198         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5199
5200         return offset;
5201 }
5202
5203 static int
5204 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5205 {
5206         guint8  wc, cmd=0xff;
5207         guint16 andxoffset=0, bc, maxcnt = 0;
5208         guint32 ofs = 0;
5209         smb_info_t *si;
5210         unsigned int fid;
5211
5212         WORD_COUNT;
5213
5214         /* next smb command */
5215         cmd = tvb_get_guint8(tvb, offset);
5216         if(cmd!=0xff){
5217                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5218         } else {
5219                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5220         }
5221         offset += 1;
5222
5223         /* reserved byte */
5224         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5225         offset += 1;
5226
5227         /* andxoffset */
5228         andxoffset = tvb_get_letohs(tvb, offset);
5229         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5230         offset += 2;
5231
5232         /* fid */
5233         fid = tvb_get_letohs(tvb, offset);
5234         add_fid(tvb, pinfo, tree, offset, 2, fid);
5235         offset += 2;
5236         if (!pinfo->fd->flags.visited) {
5237                 /* remember the FID for the processing of the response */
5238                 si = (smb_info_t *)pinfo->private_data;
5239                 si->sip->extra_info=(void *)fid;
5240         }
5241
5242         /* offset */
5243         ofs = tvb_get_letohl(tvb, offset);
5244         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5245         offset += 4;
5246
5247         /* max count */
5248         maxcnt = tvb_get_letohs(tvb, offset);
5249         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5250         offset += 2;
5251
5252         if (check_col(pinfo->cinfo, COL_INFO))
5253                 col_append_fstr(pinfo->cinfo, COL_INFO,
5254                                 ", %u byte%s at offset %u", maxcnt,
5255                                 (maxcnt == 1) ? "" : "s", ofs);
5256
5257         /* min count */
5258         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5259         offset += 2;
5260
5261         /* XXX - max count high */
5262         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5263         offset += 4;
5264
5265         /* remaining */
5266         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5267         offset += 2;
5268
5269         if(wc==12){
5270                 /* high offset */
5271                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5272                 offset += 4;
5273         }
5274
5275         BYTE_COUNT;
5276
5277         END_OF_SMB
5278
5279         /* call AndXCommand (if there are any) */
5280         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5281
5282         return offset;
5283 }
5284
5285 static int
5286 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5287 {
5288         guint8  wc, cmd=0xff;
5289         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5290         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5291         int fid=0;
5292
5293         WORD_COUNT;
5294
5295         /* next smb command */
5296         cmd = tvb_get_guint8(tvb, offset);
5297         if(cmd!=0xff){
5298                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5299         } else {
5300                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5301         }
5302         offset += 1;
5303
5304         /* reserved byte */
5305         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5306         offset += 1;
5307
5308         /* andxoffset */
5309         andxoffset = tvb_get_letohs(tvb, offset);
5310         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5311         offset += 2;
5312
5313         /* If we have seen the request, then print which FID this refers to */
5314         /* first check if we have seen the request */
5315         if(si->sip != NULL && si->sip->frame_req>0){
5316                 fid=(int)si->sip->extra_info;
5317                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5318         }
5319
5320         /* remaining */
5321         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5322         offset += 2;
5323
5324         /* data compaction mode */
5325         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5326         offset += 2;
5327
5328         /* 2 reserved bytes */
5329         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5330         offset += 2;
5331
5332         /* data len */
5333         datalen = tvb_get_letohs(tvb, offset);
5334         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5335         offset += 2;
5336
5337         if (check_col(pinfo->cinfo, COL_INFO))
5338                 col_append_fstr(pinfo->cinfo, COL_INFO,
5339                                 ", %u byte%s", datalen,
5340                                 (datalen == 1) ? "" : "s");
5341
5342         /* data offset */
5343         dataoffset=tvb_get_letohs(tvb, offset);
5344         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5345         offset += 2;
5346
5347         /* 10 reserved bytes */
5348         /* XXX - first 2 bytes are data length high, not reserved */
5349         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5350         offset += 10;
5351
5352         BYTE_COUNT;
5353
5354         /* file data, might be DCERPC on a pipe */
5355         if(bc){
5356                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5357                     top_tree, offset, bc, datalen, 0, fid);
5358                 bc = 0;
5359         }
5360
5361         END_OF_SMB
5362
5363         /* call AndXCommand (if there are any) */
5364         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5365
5366         return offset;
5367 }
5368
5369 static int
5370 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5371 {
5372         guint32 ofs=0;
5373         guint8  wc, cmd=0xff;
5374         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5375         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5376         unsigned int fid=0;
5377         guint16 mode = 0;
5378
5379
5380         WORD_COUNT;
5381
5382         /* next smb command */
5383         cmd = tvb_get_guint8(tvb, offset);
5384         if(cmd!=0xff){
5385                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5386         } else {
5387                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5388         }
5389         offset += 1;
5390
5391         /* reserved byte */
5392         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5393         offset += 1;
5394
5395         /* andxoffset */
5396         andxoffset = tvb_get_letohs(tvb, offset);
5397         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5398         offset += 2;
5399
5400         /* fid */
5401         fid = tvb_get_letohs(tvb, offset);
5402         add_fid(tvb, pinfo, tree, offset, 2, fid);
5403         offset += 2;
5404         if (!pinfo->fd->flags.visited) {
5405                 /* remember the FID for the processing of the response */
5406                 si->sip->extra_info=(void *)fid;
5407         }
5408
5409         /* offset */
5410         ofs = tvb_get_letohl(tvb, offset);
5411         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5412         offset += 4;
5413
5414         /* reserved */
5415         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5416         offset += 4;
5417
5418         /* mode */
5419         mode = tvb_get_letohs(tvb, offset);
5420         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5421
5422         /* remaining */
5423         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5424         offset += 2;
5425
5426         /* XXX - data length high */
5427         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5428         offset += 2;
5429
5430         /* data len */
5431         datalen = tvb_get_letohs(tvb, offset);
5432         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5433         offset += 2;
5434
5435         /* data offset */
5436         dataoffset=tvb_get_letohs(tvb, offset);
5437         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5438         offset += 2;
5439
5440         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5441         if (check_col(pinfo->cinfo, COL_INFO))
5442                 col_append_fstr(pinfo->cinfo, COL_INFO,
5443                                 ", %u byte%s at offset %u", datalen,
5444                                 (datalen == 1) ? "" : "s", ofs);
5445
5446         if(wc==14){
5447                 /* high offset */
5448                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5449                 offset += 4;
5450         }
5451
5452         BYTE_COUNT;
5453
5454         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5455            the first two bytes of the payload is the length of the data
5456            also this tells us that this is indeed the IPC$ share
5457            (if we didnt already know that 
5458         */
5459         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5460                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5461                 offset += 2;
5462                 dataoffset += 2;
5463                 bc -= 2;
5464                 datalen -= 2;
5465                 if(si->sip){
5466                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5467                 }
5468         }
5469
5470         /* file data, might be DCERPC on a pipe */
5471         if (bc != 0) {
5472                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5473                     top_tree, offset, bc, datalen, 0, fid);
5474                 bc = 0;
5475         }
5476
5477         END_OF_SMB
5478
5479         /* call AndXCommand (if there are any) */
5480         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5481
5482         return offset;
5483 }
5484
5485 static int
5486 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5487 {
5488         guint8  wc, cmd=0xff;
5489         guint16 andxoffset=0, bc, datalen=0;
5490         smb_info_t *si;
5491
5492         WORD_COUNT;
5493
5494         /* next smb command */
5495         cmd = tvb_get_guint8(tvb, offset);
5496         if(cmd!=0xff){
5497                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5498         } else {
5499                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5500         }
5501         offset += 1;
5502
5503         /* reserved byte */
5504         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5505         offset += 1;
5506
5507         /* andxoffset */
5508         andxoffset = tvb_get_letohs(tvb, offset);
5509         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5510         offset += 2;
5511
5512         /* If we have seen the request, then print which FID this refers to */
5513         si = (smb_info_t *)pinfo->private_data;
5514         /* first check if we have seen the request */
5515         if(si->sip != NULL && si->sip->frame_req>0){
5516                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5517         }
5518
5519         /* write count */
5520         datalen = tvb_get_letohs(tvb, offset);
5521         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5522         offset += 2;
5523
5524         if (check_col(pinfo->cinfo, COL_INFO))
5525                 col_append_fstr(pinfo->cinfo, COL_INFO,
5526                                 ", %u byte%s", datalen,
5527                                 (datalen == 1) ? "" : "s");
5528
5529         /* remaining */
5530         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5531         offset += 2;
5532
5533         /* 4 reserved bytes */
5534         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5535         offset += 4;
5536
5537         BYTE_COUNT;
5538
5539         END_OF_SMB
5540
5541         /* call AndXCommand (if there are any) */
5542         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5543
5544         return offset;
5545 }
5546
5547
5548 static const true_false_string tfs_setup_action_guest = {
5549         "Logged in as GUEST",
5550         "Not logged in as GUEST"
5551 };
5552 static int
5553 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5554 {
5555         guint16 mask;
5556         proto_item *item = NULL;
5557         proto_tree *tree = NULL;
5558
5559         mask = tvb_get_letohs(tvb, offset);
5560
5561         if(parent_tree){
5562                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5563                         "Action: 0x%04x", mask);
5564                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5565         }
5566
5567         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5568                 tvb, offset, 2, mask);
5569
5570         offset += 2;
5571
5572         return offset;
5573 }
5574
5575
5576 static int
5577 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5578 {
5579         guint8  wc, cmd=0xff;
5580         guint16 bc;
5581         guint16 andxoffset=0;
5582         smb_info_t *si = pinfo->private_data;
5583         int an_len;
5584         const char *an;
5585         int dn_len;
5586         const char *dn;
5587         guint16 pwlen=0;
5588         guint16 sbloblen=0;
5589         guint16 apwlen=0, upwlen=0;
5590
5591         WORD_COUNT;
5592
5593         /* next smb command */
5594         cmd = tvb_get_guint8(tvb, offset);
5595         if(cmd!=0xff){
5596                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5597         } else {
5598                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5599         }
5600         offset += 1;
5601
5602         /* reserved byte */
5603         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5604         offset += 1;
5605
5606         /* andxoffset */
5607         andxoffset = tvb_get_letohs(tvb, offset);
5608         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5609         offset += 2;
5610
5611         /* Maximum Buffer Size */
5612         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5613         offset += 2;
5614
5615         /* Maximum Multiplex Count */
5616         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5617         offset += 2;
5618
5619         /* VC Number */
5620         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5621         offset += 2;
5622
5623         /* session key */
5624         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5625         offset += 4;
5626
5627         switch (wc) {
5628         case 10:
5629                 /* password length, ASCII*/
5630                 pwlen = tvb_get_letohs(tvb, offset);
5631                 proto_tree_add_uint(tree, hf_smb_password_len,
5632                         tvb, offset, 2, pwlen);
5633                 offset += 2;
5634
5635                 /* 4 reserved bytes */
5636                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5637                 offset += 4;
5638
5639                 break;
5640
5641         case 12:
5642                 /* security blob length */
5643                 sbloblen = tvb_get_letohs(tvb, offset);
5644                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5645                 offset += 2;
5646
5647                 /* 4 reserved bytes */
5648                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5649                 offset += 4;
5650
5651                 /* capabilities */
5652                 dissect_negprot_capabilities(tvb, tree, offset);
5653                 offset += 4;
5654
5655                 break;
5656
5657         case 13:
5658                 /* password length, ANSI*/
5659                 apwlen = tvb_get_letohs(tvb, offset);
5660                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5661                         tvb, offset, 2, apwlen);
5662                 offset += 2;
5663
5664                 /* password length, Unicode*/
5665                 upwlen = tvb_get_letohs(tvb, offset);
5666                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5667                         tvb, offset, 2, upwlen);
5668                 offset += 2;
5669
5670                 /* 4 reserved bytes */
5671                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5672                 offset += 4;
5673
5674                 /* capabilities */
5675                 dissect_negprot_capabilities(tvb, tree, offset);
5676                 offset += 4;
5677
5678                 break;
5679         }
5680
5681         BYTE_COUNT;
5682
5683         if (wc==12) {
5684                 proto_item *blob_item;
5685
5686                 /* security blob */
5687
5688                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5689                                                 tvb, offset, sbloblen, TRUE);
5690
5691                 /* As an optimization, because Windows is perverse,
5692                    we check to see if NTLMSSP is the first part of the 
5693                    blob, and if so, call the NTLMSSP dissector,
5694                    otherwise we call the GSS-API dissector. This is because
5695                    Windows can request RAW NTLMSSP, but will happily handle
5696                    a client that wraps NTLMSSP in SPNEGO
5697                 */
5698
5699                 if(sbloblen){
5700                         tvbuff_t *blob_tvb;
5701                         proto_tree *blob_tree;
5702
5703                         blob_tree = proto_item_add_subtree(blob_item, 
5704                                                            ett_smb_secblob);
5705                         CHECK_BYTE_COUNT(sbloblen);
5706
5707                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5708                                                   sbloblen);
5709
5710                         if (si && si->ct && si->ct->raw_ntlmssp && 
5711                             !strncmp("NTLMSSP", 
5712                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5713                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5714                                          blob_tree);
5715
5716                         }
5717                         else {
5718                           call_dissector(gssapi_handle, blob_tvb, 
5719                                          pinfo, blob_tree);
5720                         }
5721
5722                         COUNT_BYTES(sbloblen);
5723                 }
5724
5725                 /* OS */
5726                 an = get_unicode_or_ascii_string(tvb, &offset,
5727                         si->unicode, &an_len, FALSE, FALSE, &bc);
5728                 if (an == NULL)
5729                         goto endofcommand;
5730                 proto_tree_add_string(tree, hf_smb_os, tvb,
5731                         offset, an_len, an);
5732                 COUNT_BYTES(an_len);
5733
5734                 /* LANMAN */
5735                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5736                  * padding/null string/whatever in front of this. W2K doesn't
5737                  * appear to. I suspect that's a bug that got fixed; I also
5738                  * suspect that, in practice, nobody ever looks at that field
5739                  * because the bug didn't appear to get fixed until NT 5.0....
5740                  */
5741                 an = get_unicode_or_ascii_string(tvb, &offset,
5742                         si->unicode, &an_len, FALSE, FALSE, &bc);
5743                 if (an == NULL)
5744                         goto endofcommand;
5745                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5746                         offset, an_len, an);
5747                 COUNT_BYTES(an_len);
5748
5749                 /* Primary domain */
5750                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5751                  * byte in front of this, at least if all the strings are
5752                  * ASCII and the account name is empty. Another bug?
5753                  */
5754                 dn = get_unicode_or_ascii_string(tvb, &offset,
5755                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5756                 if (dn == NULL)
5757                         goto endofcommand;
5758                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5759                         offset, dn_len, dn);
5760                 COUNT_BYTES(dn_len);
5761         } else {
5762                 switch (wc) {
5763
5764                 case 10:
5765                         if(pwlen){
5766                                 /* password, ASCII */
5767                                 CHECK_BYTE_COUNT(pwlen);
5768                                 proto_tree_add_item(tree, hf_smb_password,
5769                                         tvb, offset, pwlen, TRUE);
5770                                 COUNT_BYTES(pwlen);
5771                         }
5772
5773                         break;
5774
5775                 case 13:
5776                         if(apwlen){
5777                                 /* password, ANSI */
5778                                 CHECK_BYTE_COUNT(apwlen);
5779                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5780                                         tvb, offset, apwlen, TRUE);
5781                                 COUNT_BYTES(apwlen);
5782                         }
5783
5784                         if(upwlen){
5785                                 proto_item *item;
5786
5787                                 /* password, Unicode */
5788                                 CHECK_BYTE_COUNT(upwlen);
5789                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5790                                         tvb, offset, upwlen, TRUE);
5791
5792                                 if (upwlen > 24) {
5793                                         proto_tree *subtree;
5794
5795                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5796
5797                                         dissect_ntlmv2_response(
5798                                                 tvb, subtree, offset, upwlen);
5799                                 }
5800
5801                                 COUNT_BYTES(upwlen);
5802                         }
5803
5804                         break;
5805                 }
5806
5807                 /* Account Name */
5808                 an = get_unicode_or_ascii_string(tvb, &offset,
5809                         si->unicode, &an_len, FALSE, FALSE, &bc);
5810                 if (an == NULL)
5811                         goto endofcommand;
5812                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5813                         an);
5814                 COUNT_BYTES(an_len);
5815
5816                 /* Primary domain */
5817                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5818                  * byte in front of this, at least if all the strings are
5819                  * ASCII and the account name is empty. Another bug?
5820                  */
5821                 dn = get_unicode_or_ascii_string(tvb, &offset,
5822                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5823                 if (dn == NULL)
5824                         goto endofcommand;
5825                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5826                         offset, dn_len, dn);
5827                 COUNT_BYTES(dn_len);
5828
5829                 if (check_col(pinfo->cinfo, COL_INFO)) {
5830                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5831
5832                         if (!dn[0] && !an[0])
5833                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5834                                                 "anonymous");
5835                         else
5836                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5837                                                 "%s\\%s", dn,an);
5838                 }
5839
5840                 /* OS */
5841                 an = get_unicode_or_ascii_string(tvb, &offset,
5842                         si->unicode, &an_len, FALSE, FALSE, &bc);
5843                 if (an == NULL)
5844                         goto endofcommand;
5845                 proto_tree_add_string(tree, hf_smb_os, tvb,
5846                         offset, an_len, an);
5847                 COUNT_BYTES(an_len);
5848
5849                 /* LANMAN */
5850                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5851                  * padding/null string/whatever in front of this. W2K doesn't
5852                  * appear to. I suspect that's a bug that got fixed; I also
5853                  * suspect that, in practice, nobody ever looks at that field
5854                  * because the bug didn't appear to get fixed until NT 5.0....
5855                  */
5856                 an = get_unicode_or_ascii_string(tvb, &offset,
5857                         si->unicode, &an_len, FALSE, FALSE, &bc);
5858                 if (an == NULL)
5859                         goto endofcommand;
5860                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5861                         offset, an_len, an);
5862                 COUNT_BYTES(an_len);
5863         }
5864
5865         END_OF_SMB
5866
5867         /* call AndXCommand (if there are any) */
5868         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5869
5870         return offset;
5871 }
5872
5873 static int
5874 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5875 {
5876         guint8  wc, cmd=0xff;
5877         guint16 andxoffset=0, bc;
5878         guint16 sbloblen=0;
5879         smb_info_t *si = pinfo->private_data;
5880         int an_len;
5881         const char *an;
5882
5883         WORD_COUNT;
5884
5885         /* next smb command */
5886         cmd = tvb_get_guint8(tvb, offset);
5887         if(cmd!=0xff){
5888                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5889         } else {
5890                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5891         }
5892         offset += 1;
5893
5894         /* reserved byte */
5895         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5896         offset += 1;
5897
5898         /* andxoffset */
5899         andxoffset = tvb_get_letohs(tvb, offset);
5900         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5901         offset += 2;
5902
5903         /* flags */
5904         offset = dissect_setup_action(tvb, tree, offset);
5905
5906         if(wc==4){
5907                 /* security blob length */
5908                 sbloblen = tvb_get_letohs(tvb, offset);
5909                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5910                 offset += 2;
5911         }
5912
5913         BYTE_COUNT;
5914
5915         if(wc==4) {
5916                 proto_item *blob_item;
5917
5918                 /* security blob */
5919
5920                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5921                                                 tvb, offset, sbloblen, TRUE);
5922
5923                 if(sbloblen){
5924                         tvbuff_t *blob_tvb;
5925                         proto_tree *blob_tree;
5926
5927                         blob_tree = proto_item_add_subtree(blob_item, 
5928                                                            ett_smb_secblob);
5929                         CHECK_BYTE_COUNT(sbloblen);
5930
5931                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5932                                                     sbloblen);
5933
5934                         if (si && si->ct && si->ct->raw_ntlmssp && 
5935                             !strncmp("NTLMSSP", 
5936                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5937                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5938                                          blob_tree);
5939
5940                         }
5941                         else {
5942                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
5943                                          blob_tree);
5944
5945                         }
5946
5947                         COUNT_BYTES(sbloblen);
5948                 }
5949         }
5950
5951         /* OS */
5952         an = get_unicode_or_ascii_string(tvb, &offset,
5953                 si->unicode, &an_len, FALSE, FALSE, &bc);
5954         if (an == NULL)
5955                 goto endofcommand;
5956         proto_tree_add_string(tree, hf_smb_os, tvb,
5957                 offset, an_len, an);
5958         COUNT_BYTES(an_len);
5959
5960         /* LANMAN */
5961         an = get_unicode_or_ascii_string(tvb, &offset,
5962                 si->unicode, &an_len, FALSE, FALSE, &bc);
5963         if (an == NULL)
5964                 goto endofcommand;
5965         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5966                 offset, an_len, an);
5967         COUNT_BYTES(an_len);
5968
5969         if(wc==3) {
5970                 /* Primary domain */
5971                 an = get_unicode_or_ascii_string(tvb, &offset,
5972                         si->unicode, &an_len, FALSE, FALSE, &bc);
5973                 if (an == NULL)
5974                         goto endofcommand;
5975                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5976                         offset, an_len, an);
5977                 COUNT_BYTES(an_len);
5978         }
5979
5980         END_OF_SMB
5981
5982         /* call AndXCommand (if there are any) */
5983         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5984
5985         return offset;
5986 }
5987
5988
5989 static int
5990 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5991 {
5992         guint8  wc, cmd=0xff;
5993         guint16 andxoffset=0;
5994         guint16 bc;
5995
5996         WORD_COUNT;
5997
5998         /* next smb command */
5999         cmd = tvb_get_guint8(tvb, offset);
6000         if(cmd!=0xff){
6001                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6002         } else {
6003                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
6004         }
6005         offset += 1;
6006
6007         /* reserved byte */
6008         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6009         offset += 1;
6010
6011         /* andxoffset */
6012         andxoffset = tvb_get_letohs(tvb, offset);
6013         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6014         offset += 2;
6015
6016         BYTE_COUNT;
6017
6018         END_OF_SMB
6019
6020         /* call AndXCommand (if there are any) */
6021         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6022
6023         return offset;
6024 }
6025
6026
6027 static const true_false_string tfs_connect_support_search = {
6028         "Exclusive search bits supported",
6029         "Exclusive search bits not supported"
6030 };
6031 static const true_false_string tfs_connect_support_in_dfs = {
6032         "Share is in Dfs",
6033         "Share isn't in Dfs"
6034 };
6035
6036 static int
6037 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6038 {
6039         guint16 mask;
6040         proto_item *item = NULL;
6041         proto_tree *tree = NULL;
6042
6043         mask = tvb_get_letohs(tvb, offset);
6044
6045         if(parent_tree){
6046                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6047                         "Optional Support: 0x%04x", mask);
6048                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6049         }
6050
6051         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6052                 tvb, offset, 2, mask);
6053         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6054                 tvb, offset, 2, mask);
6055
6056         offset += 2;
6057
6058         return offset;
6059 }
6060
6061 static const true_false_string tfs_disconnect_tid = {
6062         "DISCONNECT TID",
6063         "Do NOT disconnect TID"
6064 };
6065
6066 static int
6067 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6068 {
6069         guint16 mask;
6070         proto_item *item = NULL;
6071         proto_tree *tree = NULL;
6072
6073         mask = tvb_get_letohs(tvb, offset);
6074
6075         if(parent_tree){
6076                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6077                         "Flags: 0x%04x", mask);
6078                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6079         }
6080
6081         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6082                 tvb, offset, 2, mask);
6083
6084         offset += 2;
6085
6086         return offset;
6087 }
6088
6089 static int
6090 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6091 {
6092         guint8  wc, cmd=0xff;
6093         guint16 bc;
6094         guint16 andxoffset=0, pwlen=0;
6095         smb_info_t *si = pinfo->private_data;
6096         int an_len;
6097         const char *an;
6098
6099         WORD_COUNT;
6100
6101         /* next smb command */
6102         cmd = tvb_get_guint8(tvb, offset);
6103         if(cmd!=0xff){
6104                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6105         } else {
6106                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6107         }
6108         offset += 1;
6109
6110         /* reserved byte */
6111         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6112         offset += 1;
6113
6114         /* andxoffset */
6115         andxoffset = tvb_get_letohs(tvb, offset);
6116         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6117         offset += 2;
6118
6119         /* flags */
6120         offset = dissect_connect_flags(tvb, tree, offset);
6121
6122         /* password length*/
6123         pwlen = tvb_get_letohs(tvb, offset);
6124         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6125         offset += 2;
6126
6127         BYTE_COUNT;
6128
6129         /* password */
6130         CHECK_BYTE_COUNT(pwlen);
6131         proto_tree_add_item(tree, hf_smb_password,
6132                 tvb, offset, pwlen, TRUE);
6133         COUNT_BYTES(pwlen);
6134
6135         /* Path */
6136         an = get_unicode_or_ascii_string(tvb, &offset,
6137                 si->unicode, &an_len, FALSE, FALSE, &bc);
6138         if (an == NULL)
6139                 goto endofcommand;
6140         proto_tree_add_string(tree, hf_smb_path, tvb,
6141                 offset, an_len, an);
6142         COUNT_BYTES(an_len);
6143
6144         if (check_col(pinfo->cinfo, COL_INFO)) {
6145                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6146         }
6147
6148         /*
6149          * NOTE: the Service string is always ASCII, even if the
6150          * "strings are Unicode" bit is set in the flags2 field
6151          * of the SMB.
6152          */
6153
6154         /* Service */
6155         /* XXX - what if this runs past bc? */
6156         an_len = tvb_strsize(tvb, offset);
6157         CHECK_BYTE_COUNT(an_len);
6158         an = tvb_get_ptr(tvb, offset, an_len);
6159         proto_tree_add_string(tree, hf_smb_service, tvb,
6160                 offset, an_len, an);
6161         COUNT_BYTES(an_len);
6162
6163         END_OF_SMB
6164
6165         /* call AndXCommand (if there are any) */
6166         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6167
6168         return offset;
6169 }
6170
6171
6172 static int
6173 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6174 {
6175         guint8  wc, wleft, cmd=0xff;
6176         guint16 andxoffset=0;
6177         guint16 bc;
6178         int an_len;
6179         const char *an;
6180         smb_info_t *si = pinfo->private_data;
6181
6182         WORD_COUNT;
6183
6184         wleft = wc;     /* this is at least 1 */
6185
6186         /* next smb command */
6187         cmd = tvb_get_guint8(tvb, offset);
6188         if(cmd!=0xff){
6189                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6190         } else {
6191                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6192         }
6193         offset += 1;
6194
6195         /* reserved byte */
6196         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6197         offset += 1;
6198
6199         wleft--;
6200         if (wleft == 0)
6201                 goto bytecount;
6202
6203         /* andxoffset */
6204         andxoffset = tvb_get_letohs(tvb, offset);
6205         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6206         offset += 2;
6207         wleft--;
6208         if (wleft == 0)
6209                 goto bytecount;
6210
6211         /* flags */
6212         offset = dissect_connect_support_bits(tvb, tree, offset);
6213         wleft--;
6214
6215         /* XXX - I've seen captures where this is 7, but I have no
6216            idea how to dissect it.  I'm guessing the third word
6217            contains connect support bits, which looks plausible
6218            from the values I've seen. */
6219
6220         while (wleft != 0) {
6221                 proto_tree_add_text(tree, tvb, offset, 2,
6222                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6223                 offset += 2;
6224                 wleft--;
6225         }
6226
6227         BYTE_COUNT;
6228
6229         /*
6230          * NOTE: even though the SNIA CIFS spec doesn't say there's
6231          * a "Service" string if there's a word count of 2, the
6232          * document at
6233          *
6234          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6235          *
6236          * (it's in an ugly format - text intended to be sent to a
6237          * printer, with backspaces and overstrikes used for boldfacing
6238          * and underlining; UNIX "col -b" can be used to strip the
6239          * overstrikes out) says there's a "Service" string there, and
6240          * some network traffic has it.
6241          */
6242
6243         /*
6244          * NOTE: the Service string is always ASCII, even if the
6245          * "strings are Unicode" bit is set in the flags2 field
6246          * of the SMB.
6247          */
6248
6249         /* Service */
6250         /* XXX - what if this runs past bc? */
6251         an_len = tvb_strsize(tvb, offset);
6252         CHECK_BYTE_COUNT(an_len);
6253         an = tvb_get_ptr(tvb, offset, an_len);
6254         proto_tree_add_string(tree, hf_smb_service, tvb,
6255                 offset, an_len, an);
6256         COUNT_BYTES(an_len);
6257
6258         /* Now when we know the service type, store it so that we know it for later commands down
6259            this tree */
6260         if(!pinfo->fd->flags.visited){
6261                 /* Remove any previous entry for this TID */
6262                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6263                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6264                 }
6265                 if(strcmp(an,"IPC") == 0){
6266                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6267                 } else {
6268                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6269                 }
6270         }
6271
6272
6273         if(wc==3){
6274                 if (bc != 0) {
6275                         /*
6276                          * Sometimes this isn't present.
6277                          */
6278
6279                         /* Native FS */
6280                         an = get_unicode_or_ascii_string(tvb, &offset,
6281                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6282                                 &bc);
6283                         if (an == NULL)
6284                                 goto endofcommand;
6285                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6286                                 offset, an_len, an);
6287                         COUNT_BYTES(an_len);
6288                 }
6289         }
6290
6291         END_OF_SMB
6292
6293         /* call AndXCommand (if there are any) */
6294         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6295
6296         return offset;
6297 }
6298
6299
6300
6301 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6302    NT Transaction command  begins here
6303    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6304 #define NT_TRANS_CREATE         1
6305 #define NT_TRANS_IOCTL          2
6306 #define NT_TRANS_SSD            3
6307 #define NT_TRANS_NOTIFY         4
6308 #define NT_TRANS_RENAME         5
6309 #define NT_TRANS_QSD            6
6310 #define NT_TRANS_GET_USER_QUOTA 7
6311 #define NT_TRANS_SET_USER_QUOTA 8
6312 const value_string nt_cmd_vals[] = {
6313         {NT_TRANS_CREATE,               "NT CREATE"},
6314         {NT_TRANS_IOCTL,                "NT IOCTL"},
6315         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6316         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6317         {NT_TRANS_RENAME,               "NT RENAME"},
6318         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6319         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6320         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6321         {0, NULL}
6322 };
6323
6324 static const value_string nt_ioctl_isfsctl_vals[] = {
6325         {0,     "Device IOCTL"},
6326         {1,     "FS control : FSCTL"},
6327         {0, NULL}
6328 };
6329
6330 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6331 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6332         "Apply the command to share root handle (MUST BE Dfs)",
6333         "Apply to this share",
6334 };
6335
6336 static const value_string nt_notify_action_vals[] = {
6337         {1,     "ADDED (object was added"},
6338         {2,     "REMOVED (object was removed)"},
6339         {3,     "MODIFIED (object was modified)"},
6340         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6341         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6342         {6,     "ADDED_STREAM (a stream was added)"},
6343         {7,     "REMOVED_STREAM (a stream was removed)"},
6344         {8,     "MODIFIED_STREAM (a stream was modified)"},
6345         {0, NULL}
6346 };
6347
6348 static const value_string watch_tree_vals[] = {
6349         {0,     "Current directory only"},
6350         {1,     "Subdirectories also"},
6351         {0, NULL}
6352 };
6353
6354 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6355 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6356 #define NT_NOTIFY_STREAM_NAME   0x00000200
6357 #define NT_NOTIFY_SECURITY      0x00000100
6358 #define NT_NOTIFY_EA            0x00000080
6359 #define NT_NOTIFY_CREATION      0x00000040
6360 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6361 #define NT_NOTIFY_LAST_WRITE    0x00000010
6362 #define NT_NOTIFY_SIZE          0x00000008
6363 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6364 #define NT_NOTIFY_DIR_NAME      0x00000002
6365 #define NT_NOTIFY_FILE_NAME     0x00000001
6366 static const true_false_string tfs_nt_notify_stream_write = {
6367         "Notify on changes to STREAM WRITE",
6368         "Do NOT notify on changes to stream write",
6369 };
6370 static const true_false_string tfs_nt_notify_stream_size = {
6371         "Notify on changes to STREAM SIZE",
6372         "Do NOT notify on changes to stream size",
6373 };
6374 static const true_false_string tfs_nt_notify_stream_name = {
6375         "Notify on changes to STREAM NAME",
6376         "Do NOT notify on changes to stream name",
6377 };
6378 static const true_false_string tfs_nt_notify_security = {
6379         "Notify on changes to SECURITY",
6380         "Do NOT notify on changes to security",
6381 };
6382 static const true_false_string tfs_nt_notify_ea = {
6383         "Notify on changes to EA",
6384         "Do NOT notify on changes to EA",
6385 };
6386 static const true_false_string tfs_nt_notify_creation = {
6387         "Notify on changes to CREATION TIME",
6388         "Do NOT notify on changes to creation time",
6389 };
6390 static const true_false_string tfs_nt_notify_last_access = {
6391         "Notify on changes to LAST ACCESS TIME",
6392         "Do NOT notify on changes to last access time",
6393 };
6394 static const true_false_string tfs_nt_notify_last_write = {
6395         "Notify on changes to LAST WRITE TIME",
6396         "Do NOT notify on changes to last write time",
6397 };
6398 static const true_false_string tfs_nt_notify_size = {
6399         "Notify on changes to SIZE",
6400         "Do NOT notify on changes to size",
6401 };
6402 static const true_false_string tfs_nt_notify_attributes = {
6403         "Notify on changes to ATTRIBUTES",
6404         "Do NOT notify on changes to attributes",
6405 };
6406 static const true_false_string tfs_nt_notify_dir_name = {
6407         "Notify on changes to DIR NAME",
6408         "Do NOT notify on changes to dir name",
6409 };
6410 static const true_false_string tfs_nt_notify_file_name = {
6411         "Notify on changes to FILE NAME",
6412         "Do NOT notify on changes to file name",
6413 };
6414
6415 static const value_string create_disposition_vals[] = {
6416         {0,     "Supersede (supersede existing file (if it exists))"},
6417         {1,     "Open (if file exists open it, else fail)"},
6418         {2,     "Create (if file exists fail, else create it)"},
6419         {3,     "Open If (if file exists open it, else create it)"},
6420         {4,     "Overwrite (if file exists overwrite, else fail)"},
6421         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6422         {0, NULL}
6423 };
6424
6425 static const value_string impersonation_level_vals[] = {
6426         {0,     "Anonymous"},
6427         {1,     "Identification"},
6428         {2,     "Impersonation"},
6429         {3,     "Delegation"},
6430         {0, NULL}
6431 };
6432
6433 static const true_false_string tfs_nt_security_flags_context_tracking = {
6434         "Security tracking mode is DYNAMIC",
6435         "Security tracking mode is STATIC",
6436 };
6437
6438 static const true_false_string tfs_nt_security_flags_effective_only = {
6439         "ONLY ENABLED aspects of the client's security context are available",
6440         "ALL aspects of the client's security context are available",
6441 };
6442
6443 static const true_false_string tfs_nt_create_bits_oplock = {
6444         "Requesting OPLOCK",
6445         "Does NOT request oplock"
6446 };
6447
6448 static const true_false_string tfs_nt_create_bits_boplock = {
6449         "Requesting BATCH OPLOCK",
6450         "Does NOT request batch oplock"
6451 };
6452
6453 /*
6454  * XXX - must be a directory, and can be a file, or can be a directory,
6455  * and must be a file?
6456  */
6457 static const true_false_string tfs_nt_create_bits_dir = {
6458         "Target of open MUST be a DIRECTORY",
6459         "Target of open can be a file"
6460 };
6461
6462 static const true_false_string tfs_nt_create_bits_ext_resp = {
6463   "Extended responses required",
6464   "Extended responses NOT required"
6465 };
6466
6467 static const true_false_string tfs_nt_access_mask_generic_read = {
6468         "GENERIC READ is set",
6469         "Generic read is NOT set"
6470 };
6471 static const true_false_string tfs_nt_access_mask_generic_write = {
6472         "GENERIC WRITE is set",
6473         "Generic write is NOT set"
6474 };
6475 static const true_false_string tfs_nt_access_mask_generic_execute = {
6476         "GENERIC EXECUTE is set",
6477         "Generic execute is NOT set"
6478 };
6479 static const true_false_string tfs_nt_access_mask_generic_all = {
6480         "GENERIC ALL is set",
6481         "Generic all is NOT set"
6482 };
6483 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6484         "MAXIMUM ALLOWED is set",
6485         "Maximum allowed is NOT set"
6486 };
6487 static const true_false_string tfs_nt_access_mask_system_security = {
6488         "SYSTEM SECURITY is set",
6489         "System security is NOT set"
6490 };
6491 static const true_false_string tfs_nt_access_mask_synchronize = {
6492         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6493         "Can NOT wait on handle to synchronize on completion of I/O"
6494 };
6495 static const true_false_string tfs_nt_access_mask_write_owner = {
6496         "Can WRITE OWNER (take ownership)",
6497         "Can NOT write owner (take ownership)"
6498 };
6499 static const true_false_string tfs_nt_access_mask_write_dac = {
6500         "OWNER may WRITE the DAC",
6501         "Owner may NOT write to the DAC"
6502 };
6503 static const true_false_string tfs_nt_access_mask_read_control = {
6504         "READ ACCESS to owner, group and ACL of the SID",
6505         "Read access is NOT granted to owner, group and ACL of the SID"
6506 };
6507 static const true_false_string tfs_nt_access_mask_delete = {
6508         "DELETE access",
6509         "NO delete access"
6510 };
6511 static const true_false_string tfs_nt_access_mask_write_attributes = {
6512         "WRITE ATTRIBUTES access",
6513         "NO write attributes access"
6514 };
6515 static const true_false_string tfs_nt_access_mask_read_attributes = {
6516         "READ ATTRIBUTES access",
6517         "NO read attributes access"
6518 };
6519 static const true_false_string tfs_nt_access_mask_delete_child = {
6520         "DELETE CHILD access",
6521         "NO delete child access"
6522 };
6523 static const true_false_string tfs_nt_access_mask_execute = {
6524         "EXECUTE access",
6525         "NO execute access"
6526 };
6527 static const true_false_string tfs_nt_access_mask_write_ea = {
6528         "WRITE EXTENDED ATTRIBUTES access",
6529         "NO write extended attributes access"
6530 };
6531 static const true_false_string tfs_nt_access_mask_read_ea = {
6532         "READ EXTENDED ATTRIBUTES access",
6533         "NO read extended attributes access"
6534 };
6535 static const true_false_string tfs_nt_access_mask_append = {
6536         "APPEND access",
6537         "NO append access"
6538 };
6539 static const true_false_string tfs_nt_access_mask_write = {
6540         "WRITE access",
6541         "NO write access"
6542 };
6543 static const true_false_string tfs_nt_access_mask_read = {
6544         "READ access",
6545         "NO read access"
6546 };
6547
6548 static const true_false_string tfs_nt_share_access_delete = {
6549         "Object can be shared for DELETE",
6550         "Object can NOT be shared for delete"
6551 };
6552 static const true_false_string tfs_nt_share_access_write = {
6553         "Object can be shared for WRITE",
6554         "Object can NOT be shared for write"
6555 };
6556 static const true_false_string tfs_nt_share_access_read = {
6557         "Object can be shared for READ",
6558         "Object can NOT be shared for read"
6559 };
6560
6561 static const value_string oplock_level_vals[] = {
6562         {0,     "No oplock granted"},
6563         {1,     "Exclusive oplock granted"},
6564         {2,     "Batch oplock granted"},
6565         {3,     "Level II oplock granted"},
6566         {0, NULL}
6567 };
6568
6569 static const value_string device_type_vals[] = {
6570         {0x00000001,    "Beep"},
6571         {0x00000002,    "CDROM"},
6572         {0x00000003,    "CDROM Filesystem"},
6573         {0x00000004,    "Controller"},
6574         {0x00000005,    "Datalink"},
6575         {0x00000006,    "Dfs"},
6576         {0x00000007,    "Disk"},
6577         {0x00000008,    "Disk Filesystem"},
6578         {0x00000009,    "Filesystem"},
6579         {0x0000000a,    "Inport Port"},
6580         {0x0000000b,    "Keyboard"},
6581         {0x0000000c,    "Mailslot"},
6582         {0x0000000d,    "MIDI-In"},
6583         {0x0000000e,    "MIDI-Out"},
6584         {0x0000000f,    "Mouse"},
6585         {0x00000010,    "Multi UNC Provider"},
6586         {0x00000011,    "Named Pipe"},
6587         {0x00000012,    "Network"},
6588         {0x00000013,    "Network Browser"},
6589         {0x00000014,    "Network Filesystem"},
6590         {0x00000015,    "NULL"},
6591         {0x00000016,    "Parallel Port"},
6592         {0x00000017,    "Physical card"},
6593         {0x00000018,    "Printer"},
6594         {0x00000019,    "Scanner"},
6595         {0x0000001a,    "Serial Mouse port"},
6596         {0x0000001b,    "Serial port"},
6597         {0x0000001c,    "Screen"},
6598         {0x0000001d,    "Sound"},
6599         {0x0000001e,    "Streams"},
6600         {0x0000001f,    "Tape"},
6601         {0x00000020,    "Tape Filesystem"},
6602         {0x00000021,    "Transport"},
6603         {0x00000022,    "Unknown"},
6604         {0x00000023,    "Video"},
6605         {0x00000024,    "Virtual Disk"},
6606         {0x00000025,    "WAVE-In"},
6607         {0x00000026,    "WAVE-Out"},
6608         {0x00000027,    "8042 Port"},
6609         {0x00000028,    "Network Redirector"},
6610         {0x00000029,    "Battery"},
6611         {0x0000002a,    "Bus Extender"},
6612         {0x0000002b,    "Modem"},
6613         {0x0000002c,    "VDM"},
6614         {0,     NULL}
6615 };
6616
6617 static const value_string is_directory_vals[] = {
6618         {0,     "This is NOT a directory"},
6619         {1,     "This is a DIRECTORY"},
6620         {0, NULL}
6621 };
6622
6623 typedef struct _nt_trans_data {
6624         int subcmd;
6625         guint32 sd_len;
6626         guint32 ea_len;
6627 } nt_trans_data;
6628
6629
6630
6631 static int
6632 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6633 {
6634         guint8 mask;
6635         proto_item *item = NULL;
6636         proto_tree *tree = NULL;
6637
6638         mask = tvb_get_guint8(tvb, offset);
6639
6640         if(parent_tree){
6641                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6642                         "Security Flags: 0x%02x", mask);
6643                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6644         }
6645
6646         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6647                 tvb, offset, 1, mask);
6648         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6649                 tvb, offset, 1, mask);
6650
6651         offset += 1;
6652
6653         return offset;
6654 }
6655
6656 static int
6657 dissect_nt_share_access(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                         "Share Access: 0x%08x", mask);
6668                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6669         }
6670
6671         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6672                 tvb, offset, 4, mask);
6673         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6674                 tvb, offset, 4, mask);
6675         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6676                 tvb, offset, 4, mask);
6677
6678         offset += 4;
6679
6680         return offset;
6681 }
6682
6683 /* FIXME: need to call dissect_nt_access_mask() instead */
6684
6685 static int
6686 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6687 {
6688         guint32 mask;
6689         proto_item *item = NULL;
6690         proto_tree *tree = NULL;
6691
6692         mask = tvb_get_letohl(tvb, offset);
6693
6694         if(parent_tree){
6695                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6696                         "Access Mask: 0x%08x", mask);
6697                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6698         }
6699
6700         /*
6701          * Some of these bits come from
6702          *
6703          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6704          *
6705          * and others come from the section on ZwOpenFile in "Windows(R)
6706          * NT(R)/2000 Native API Reference".
6707          */
6708         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6709                 tvb, offset, 4, mask);
6710         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6711                 tvb, offset, 4, mask);
6712         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6713                 tvb, offset, 4, mask);
6714         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6715                 tvb, offset, 4, mask);
6716         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6717                 tvb, offset, 4, mask);
6718         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6719                 tvb, offset, 4, mask);
6720         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6721                 tvb, offset, 4, mask);
6722         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6723                 tvb, offset, 4, mask);
6724         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6725                 tvb, offset, 4, mask);
6726         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6727                 tvb, offset, 4, mask);
6728         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6729                 tvb, offset, 4, mask);
6730         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6731                 tvb, offset, 4, mask);
6732         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6733                 tvb, offset, 4, mask);
6734         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6735                 tvb, offset, 4, mask);
6736         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6737                 tvb, offset, 4, mask);
6738         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6739                 tvb, offset, 4, mask);
6740         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6741                 tvb, offset, 4, mask);
6742         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6743                 tvb, offset, 4, mask);
6744         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6745                 tvb, offset, 4, mask);
6746         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6747                 tvb, offset, 4, mask);
6748
6749         offset += 4;
6750
6751         return offset;
6752 }
6753
6754 static int
6755 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6756 {
6757         guint32 mask;
6758         proto_item *item = NULL;
6759         proto_tree *tree = NULL;
6760
6761         mask = tvb_get_letohl(tvb, offset);
6762
6763         if(parent_tree){
6764                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6765                         "Create Flags: 0x%08x", mask);
6766                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6767         }
6768
6769         /*
6770          * XXX - it's 0x00000016 in at least one capture, but
6771          * Network Monitor doesn't say what the 0x00000010 bit is.
6772          * Does the Win32 API documentation, or NT Native API book,
6773          * suggest anything?
6774          *
6775          * That is the extended response desired bit ... RJS, from Samba
6776          * Well, maybe. Samba thinks it is, and uses it to encode
6777          * OpLock granted as the high order bit of the Action field
6778          * in the response. However, Windows does not do that. Or at least
6779          * Win2K doesn't.
6780          */
6781         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6782                                tvb, offset, 4, mask);
6783         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6784                 tvb, offset, 4, mask);
6785         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6786                 tvb, offset, 4, mask);
6787         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6788                 tvb, offset, 4, mask);
6789
6790         offset += 4;
6791
6792         return offset;
6793 }
6794
6795 /*
6796  * XXX - there are some more flags in the description of "ZwOpenFile()"
6797  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6798  * the wire as well?  (The spec at
6799  *
6800  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6801  *
6802  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6803  * via the SMB protocol.  The NT redirector should convert this option
6804  * to FILE_WRITE_THROUGH."
6805  *
6806  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6807  * values one would infer from their position in the list of flags for
6808  * "ZwOpenFile()".  Most of the others probably have those values
6809  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6810  * which might go over the wire (for the benefit of backup/restore software).
6811  */
6812 static const true_false_string tfs_nt_create_options_directory = {
6813         "File being created/opened must be a directory",
6814         "File being created/opened must not be a directory"
6815 };
6816 static const true_false_string tfs_nt_create_options_write_through = {
6817         "Writes should flush buffered data before completing",
6818         "Writes need not flush buffered data before completing"
6819 };
6820 static const true_false_string tfs_nt_create_options_sequential_only = {
6821         "The file will only be accessed sequentially",
6822         "The file might not only be accessed sequentially"
6823 };
6824 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6825         "All operations SYNCHRONOUS, waits subject to termination from alert",
6826         "Operations NOT necessarily synchronous"
6827 };
6828 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6829         "All operations SYNCHRONOUS, waits not subject to alert",
6830         "Operations NOT necessarily synchronous"
6831 };
6832 static const true_false_string tfs_nt_create_options_non_directory = {
6833         "File being created/opened must not be a directory",
6834         "File being created/opened must be a directory"
6835 };
6836 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6837         "The client does not understand extended attributes",
6838         "The client understands extended attributes"
6839 };
6840 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6841         "The client understands only 8.3 file names",
6842         "The client understands long file names"
6843 };
6844 static const true_false_string tfs_nt_create_options_random_access = {
6845         "The file will be accessed randomly",
6846         "The file will not be accessed randomly"
6847 };
6848 static const true_false_string tfs_nt_create_options_delete_on_close = {
6849         "The file should be deleted when it is closed",
6850         "The file should not be deleted when it is closed"
6851 };
6852
6853 static int
6854 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6855 {
6856         guint32 mask;
6857         proto_item *item = NULL;
6858         proto_tree *tree = NULL;
6859
6860         mask = tvb_get_letohl(tvb, offset);
6861
6862         if(parent_tree){
6863                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6864                         "Create Options: 0x%08x", mask);
6865                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6866         }
6867
6868         /*
6869          * From
6870          *
6871          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6872          */
6873         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6874                 tvb, offset, 4, mask);
6875         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6876                 tvb, offset, 4, mask);
6877         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6878                 tvb, offset, 4, mask);
6879         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6880                 tvb, offset, 4, mask);
6881         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6882                 tvb, offset, 4, mask);
6883         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6884                 tvb, offset, 4, mask);
6885         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6886                 tvb, offset, 4, mask);
6887         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6888                 tvb, offset, 4, mask);
6889         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6890                 tvb, offset, 4, mask);
6891         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6892                 tvb, offset, 4, mask);
6893
6894         offset += 4;
6895
6896         return offset;
6897 }
6898
6899 static int
6900 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6901 {
6902         guint32 mask;
6903         proto_item *item = NULL;
6904         proto_tree *tree = NULL;
6905
6906         mask = tvb_get_letohl(tvb, offset);
6907
6908         if(parent_tree){
6909                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6910                         "Completion Filter: 0x%08x", mask);
6911                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6912         }
6913
6914         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6915                 tvb, offset, 4, mask);
6916         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6917                 tvb, offset, 4, mask);
6918         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6919                 tvb, offset, 4, mask);
6920         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6921                 tvb, offset, 4, mask);
6922         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6923                 tvb, offset, 4, mask);
6924         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6925                 tvb, offset, 4, mask);
6926         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6927                 tvb, offset, 4, mask);
6928         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6929                 tvb, offset, 4, mask);
6930         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6931                 tvb, offset, 4, mask);
6932         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6933                 tvb, offset, 4, mask);
6934         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6935                 tvb, offset, 4, mask);
6936         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6937                 tvb, offset, 4, mask);
6938
6939         offset += 4;
6940         return offset;
6941 }
6942
6943 static int
6944 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6945 {
6946         guint8 mask;
6947         proto_item *item = NULL;
6948         proto_tree *tree = NULL;
6949
6950         mask = tvb_get_guint8(tvb, offset);
6951
6952         if(parent_tree){
6953                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6954                         "Completion Filter: 0x%02x", mask);
6955                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6956         }
6957
6958         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6959                 tvb, offset, 1, mask);
6960
6961         offset += 1;
6962         return offset;
6963 }
6964
6965 /*
6966  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6967  * Native API Reference".
6968  */
6969 static const true_false_string tfs_nt_qsd_owner = {
6970         "Requesting OWNER security information",
6971         "NOT requesting owner security information",
6972 };
6973
6974 static const true_false_string tfs_nt_qsd_group = {
6975         "Requesting GROUP security information",
6976         "NOT requesting group security information",
6977 };
6978
6979 static const true_false_string tfs_nt_qsd_dacl = {
6980         "Requesting DACL security information",
6981         "NOT requesting DACL security information",
6982 };
6983
6984 static const true_false_string tfs_nt_qsd_sacl = {
6985         "Requesting SACL security information",
6986         "NOT requesting SACL security information",
6987 };
6988
6989 #define NT_QSD_OWNER    0x00000001
6990 #define NT_QSD_GROUP    0x00000002
6991 #define NT_QSD_DACL     0x00000004
6992 #define NT_QSD_SACL     0x00000008
6993
6994 static int
6995 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6996 {
6997         guint32 mask;
6998         proto_item *item = NULL;
6999         proto_tree *tree = NULL;
7000
7001         mask = tvb_get_letohl(tvb, offset);
7002
7003         if(parent_tree){
7004                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7005                         "Security Information: 0x%08x", mask);
7006                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7007         }
7008
7009         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7010                 tvb, offset, 4, mask);
7011         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7012                 tvb, offset, 4, mask);
7013         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7014                 tvb, offset, 4, mask);
7015         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7016                 tvb, offset, 4, mask);
7017
7018         offset += 4;
7019
7020         return offset;
7021 }
7022
7023 static void
7024 free_g_string(void *arg)
7025 {
7026         g_string_free(arg, TRUE);
7027 }
7028
7029 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7030    the SID in the 'sid_str' parameter which must be freed by the caller.
7031    hf_sid can be -1 if the caller doesnt care what name is used and then 
7032    "smb.sid" will be the default instead. If the caller wants a more
7033    appropriate hf field, it will just pass a FT_STRING hf field here
7034 */
7035
7036 int
7037 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7038                char **sid_str, int hf_sid)
7039 {
7040         proto_item *item = NULL;
7041         proto_tree *tree = NULL;
7042         int old_offset = offset, sa_offset = offset;
7043         gboolean rid_present;
7044         guint rid=0;
7045         int rid_offset=0;
7046         guint8 revision;
7047         int rev_offset;
7048         guint8 num_auth;
7049         int na_offset;
7050         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7051         int i;
7052         GString *gstr;
7053         char sid_string[245];
7054         char *sid_name;
7055
7056         if(hf_sid==-1){
7057                 hf_sid=hf_smb_sid;
7058         }
7059
7060         /* revision of sid */
7061         revision = tvb_get_guint8(tvb, offset);
7062         rev_offset = offset;
7063         offset += 1;
7064
7065         switch(revision){
7066         case 1:
7067         case 2:  /* Not sure what the different revision numbers mean */
7068           /* number of authorities*/
7069           num_auth = tvb_get_guint8(tvb, offset);
7070           na_offset = offset;
7071           offset += 1;
7072
7073           /* XXX perhaps we should have these thing searchable?
7074              a new FT_xxx thingie? SMB is quite common!*/
7075           /* identifier authorities */
7076
7077           for(i=0;i<6;i++){
7078             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7079
7080             offset++;
7081           }
7082
7083           sa_offset = offset;
7084
7085           gstr = g_string_new("");
7086
7087           CLEANUP_PUSH(free_g_string, gstr);
7088
7089           /* sub authorities, leave RID to last */
7090           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7091             /*
7092              * XXX should not be letohl but native byteorder according to
7093              * Samba header files.
7094              *
7095              * However, considering that there were never any NT ports
7096              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7097              * and IA-64 runs little-endian, as does x86-64), we can (?)
7098              * assume that non le byte encodings will be "uncommon"?
7099              */
7100              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7101                   tvb_get_letohl(tvb, offset));
7102              offset+=4;
7103           }
7104
7105
7106           if (num_auth > 4) {
7107             rid = tvb_get_letohl(tvb, offset);
7108             rid_present=TRUE;
7109             rid_offset=offset;
7110             offset+=4;
7111             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7112           } else {
7113             rid_present=FALSE;
7114             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7115           }
7116
7117           sid_name=NULL;
7118           if(sid_name_snooping){
7119             sid_name=find_sid_name(sid_string);
7120           }
7121
7122           if(parent_tree){
7123             if(sid_name){
7124               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);
7125             } else {
7126               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7127             }
7128             tree = proto_item_add_subtree(item, ett_smb_sid);
7129           }
7130
7131           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7132           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7133           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7134           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7135
7136           if(rid_present){
7137             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7138           }
7139
7140           if(sid_str){
7141             if(sid_name){
7142               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7143             } else {
7144               *sid_str = g_strdup(sid_string);
7145             }
7146           }
7147
7148           CLEANUP_CALL_AND_POP;
7149         }
7150
7151
7152         return offset;
7153 }
7154
7155
7156 static const value_string ace_type_vals[] = {
7157   { 0, "Access Allowed"},
7158   { 1, "Access Denied"},
7159   { 2, "System Audit"},
7160   { 3, "System Alarm"},
7161   { 0, NULL}
7162 };
7163 static const true_false_string tfs_ace_flags_object_inherit = {
7164   "Subordinate files will inherit this ACE",
7165   "Subordinate files will not inherit this ACE"
7166 };
7167 static const true_false_string tfs_ace_flags_container_inherit = {
7168   "Subordinate containers will inherit this ACE",
7169   "Subordinate containers will not inherit this ACE"
7170 };
7171 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7172   "Subordinate object will not propagate the inherited ACE further",
7173   "Subordinate object will propagate the inherited ACE further"
7174 };
7175 static const true_false_string tfs_ace_flags_inherit_only = {
7176   "This ACE does not apply to the current object",
7177   "This ACE applies to the current object"
7178 };
7179 static const true_false_string tfs_ace_flags_inherited_ace = {
7180   "This ACE was inherited from its parent object",
7181   "This ACE was not inherited from its parent object"
7182 };
7183 static const true_false_string tfs_ace_flags_successful_access = {
7184   "Successful accesses will be audited",
7185   "Successful accesses will not be audited"
7186 };
7187 static const true_false_string tfs_ace_flags_failed_access = {
7188   "Failed accesses will be audited",
7189   "Failed accesses will not be audited"
7190 };
7191
7192 #define APPEND_ACE_TEXT(flag, item, string) \
7193         if(flag){                                                       \
7194                 if(item)                                                \
7195                         proto_item_append_text(item, string, sep);      \
7196                 sep = ", ";                                             \
7197         }
7198
7199 static int
7200 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7201                         guint8 *data)
7202 {
7203         proto_item *item = NULL;
7204         proto_tree *tree = NULL;
7205         guint8 mask;
7206         char *sep = " ";
7207
7208         mask = tvb_get_guint8(tvb, offset);
7209
7210         if (data)
7211                 *data = mask;
7212
7213
7214         if(parent_tree){
7215                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7216                                            "NT ACE Flags: 0x%02x", mask);
7217                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7218         }
7219
7220         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7221                        tvb, offset, 1, mask);
7222         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7223
7224         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7225                        tvb, offset, 1, mask);
7226         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7227
7228         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7229                        tvb, offset, 1, mask);
7230         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7231
7232         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7233                        tvb, offset, 1, mask);
7234         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7235
7236         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7237                        tvb, offset, 1, mask);
7238         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7239
7240         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7241                        tvb, offset, 1, mask);
7242         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7243
7244         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7245                        tvb, offset, 1, mask);
7246         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7247
7248
7249         offset += 1;
7250         return offset;
7251 }
7252
7253 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7254
7255 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7256
7257 */
7258
7259 static gint ett_nt_access_mask = -1;
7260 static gint ett_nt_access_mask_generic = -1;
7261 static gint ett_nt_access_mask_standard = -1;
7262 static gint ett_nt_access_mask_specific = -1;
7263
7264 static int hf_access_sacl = -1;
7265 static int hf_access_maximum_allowed = -1;
7266 static int hf_access_generic_read = -1;
7267 static int hf_access_generic_write = -1;
7268 static int hf_access_generic_execute = -1;
7269 static int hf_access_generic_all = -1;
7270 static int hf_access_standard_delete = -1;
7271 static int hf_access_standard_read_control = -1;
7272 static int hf_access_standard_synchronise = -1;
7273 static int hf_access_standard_write_dac = -1;
7274 static int hf_access_standard_write_owner = -1;
7275 static int hf_access_specific_15 = -1;
7276 static int hf_access_specific_14 = -1;
7277 static int hf_access_specific_13 = -1;
7278 static int hf_access_specific_12 = -1;
7279 static int hf_access_specific_11 = -1;
7280 static int hf_access_specific_10 = -1;
7281 static int hf_access_specific_9 = -1;
7282 static int hf_access_specific_8 = -1;
7283 static int hf_access_specific_7 = -1;
7284 static int hf_access_specific_6 = -1;
7285 static int hf_access_specific_5 = -1;
7286 static int hf_access_specific_4 = -1;
7287 static int hf_access_specific_3 = -1;
7288 static int hf_access_specific_2 = -1;
7289 static int hf_access_specific_1 = -1;
7290 static int hf_access_specific_0 = -1;
7291
7292 /* Map generic permissions to specific permissions */
7293
7294 static void map_generic_access(guint32 *access_mask, 
7295                                struct generic_mapping *mapping)
7296 {
7297         if (*access_mask & GENERIC_READ_ACCESS) {
7298                 *access_mask &= ~GENERIC_READ_ACCESS;
7299                 *access_mask |= mapping->generic_read;
7300         }
7301
7302         if (*access_mask & GENERIC_WRITE_ACCESS) {
7303                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7304                 *access_mask |= mapping->generic_write;
7305         }
7306
7307         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7308                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7309                 *access_mask |= mapping->generic_execute;
7310         }
7311
7312         if (*access_mask & GENERIC_ALL_ACCESS) {
7313                 *access_mask &= ~GENERIC_ALL_ACCESS;
7314                 *access_mask |= mapping->generic_all;
7315         }
7316 }
7317
7318 /* Map standard permissions to specific permissions */
7319
7320 static void map_standard_access(guint32 *access_mask,
7321                                 struct standard_mapping *mapping)
7322 {
7323         if (*access_mask & READ_CONTROL_ACCESS) {
7324                 *access_mask &= ~READ_CONTROL_ACCESS;
7325                 *access_mask |= mapping->std_read;
7326         }
7327
7328         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7329                             SYNCHRONIZE_ACCESS)) {
7330                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7331                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7332                 *access_mask |= mapping->std_all;
7333         }
7334
7335 }
7336
7337 int
7338 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7339                        proto_tree *tree, char *drep, int hfindex,
7340                        struct access_mask_info *ami)
7341 {
7342         proto_item *item;
7343         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7344         guint32 access;
7345
7346         if (drep != NULL) {
7347                 /*
7348                  * Called from a DCE RPC protocol dissector, for a
7349                  * protocol where a 32-bit NDR integer contains
7350                  * an NT access mask; extract the access mask
7351                  * with an NDR call.
7352                  */
7353                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7354                                             hfindex, &access);
7355         } else {
7356                 /*
7357                  * Called from SMB, where the access mask is just a
7358                  * 4-byte little-endian quantity with no special
7359                  * NDR alignment requirement; extract it with
7360                  * "tvb_get_letohl()".
7361                  */
7362                 access = tvb_get_letohl(tvb, offset);
7363                 offset += 4;
7364         }
7365
7366         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7367
7368         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7369
7370         /* Generic access rights */
7371
7372         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7373                                    "Generic rights: 0x%08x",
7374                                    access & GENERIC_RIGHTS_MASK);
7375
7376         generic_tree = proto_item_add_subtree(
7377                 item, ett_nt_access_mask_generic);
7378
7379         proto_tree_add_boolean(
7380                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7381                 access);
7382
7383         proto_tree_add_boolean(
7384                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7385                 access);
7386
7387         proto_tree_add_boolean(
7388                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7389                 access);
7390
7391         proto_tree_add_boolean(
7392                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7393                 access);
7394
7395         /* Reserved (??) */
7396
7397         proto_tree_add_boolean(
7398                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7399                 access);
7400
7401         /* Access system security */
7402
7403         proto_tree_add_boolean(
7404                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7405                 access);
7406
7407         /* Standard access rights */
7408
7409         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7410                                    "Standard rights: 0x%08x",
7411                                    access & STANDARD_RIGHTS_MASK);
7412
7413         standard_tree = proto_item_add_subtree(
7414                 item, ett_nt_access_mask_standard);
7415
7416         proto_tree_add_boolean(
7417                 standard_tree, hf_access_standard_synchronise, tvb, 
7418                 offset - 4, 4, access);
7419
7420         proto_tree_add_boolean(
7421                 standard_tree, hf_access_standard_write_owner, tvb, 
7422                 offset - 4, 4, access);
7423
7424         proto_tree_add_boolean(
7425                 standard_tree, hf_access_standard_write_dac, tvb, 
7426                 offset - 4, 4, access);
7427
7428         proto_tree_add_boolean(
7429                 standard_tree, hf_access_standard_read_control, tvb, 
7430                 offset - 4, 4, access);
7431
7432         proto_tree_add_boolean(
7433                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7434                 access);
7435
7436         /* Specific access rights.  Call the specific_rights_fn
7437            pointer if we have one, otherwise just display bits 0-15 in
7438            boring fashion. */
7439
7440         if (ami && ami->specific_rights_name)
7441                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7442                                            "%s specific rights: 0x%08x",
7443                                            ami->specific_rights_name,
7444                                            access & SPECIFIC_RIGHTS_MASK);
7445         else
7446                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7447                                            "Specific rights: 0x%08x",
7448                                            access & SPECIFIC_RIGHTS_MASK);
7449
7450         specific_tree = proto_item_add_subtree(
7451                 item, ett_nt_access_mask_specific);
7452
7453         if (ami && ami->specific_rights_fn) {
7454                 guint32 mapped_access = access;
7455                 proto_tree *specific_mapped;
7456
7457                 specific_mapped = proto_item_add_subtree(
7458                         item, ett_nt_access_mask_specific);
7459
7460                 ami->specific_rights_fn(
7461                         tvb, offset - 4, specific_tree, access);
7462
7463                 if (ami->generic_mapping)
7464                         map_generic_access(&access, ami->generic_mapping);
7465                 
7466                 if (ami->standard_mapping)
7467                         map_standard_access(&access, ami->standard_mapping);
7468
7469                 if (access != mapped_access) {
7470                         ami->specific_rights_fn(
7471                                 tvb, offset - 4, specific_mapped, 
7472                                 mapped_access);
7473                 }
7474                 
7475                 return offset;
7476         }
7477
7478         proto_tree_add_boolean(
7479                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7480                 access);
7481
7482         proto_tree_add_boolean(
7483                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7484                 access);
7485
7486         proto_tree_add_boolean(
7487                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7488                 access);
7489
7490         proto_tree_add_boolean(
7491                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7492                 access);
7493
7494         proto_tree_add_boolean(
7495                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7496                 access);
7497
7498         proto_tree_add_boolean(
7499                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7500                 access);
7501
7502         proto_tree_add_boolean(
7503                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7504                 access);
7505
7506         proto_tree_add_boolean(
7507                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7508                 access);
7509
7510         proto_tree_add_boolean(
7511                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7512                 access);
7513
7514         proto_tree_add_boolean(
7515                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7516                 access);
7517
7518         proto_tree_add_boolean(
7519                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7520                 access);
7521
7522         proto_tree_add_boolean(
7523                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7524                 access);
7525
7526         proto_tree_add_boolean(
7527                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7528                 access);
7529
7530         proto_tree_add_boolean(
7531                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7532                 access);
7533
7534         proto_tree_add_boolean(
7535                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7536                 access);
7537
7538         proto_tree_add_boolean(
7539                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7540                 access);
7541
7542         return offset;
7543 }
7544
7545 static int hf_smb_access_mask = -1;
7546
7547 static int
7548 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7549                   proto_tree *parent_tree, char *drep,
7550                   struct access_mask_info *ami)
7551 {
7552         proto_item *item = NULL;
7553         proto_tree *tree = NULL;
7554         int old_offset = offset;
7555         guint16 size;
7556         char *sid_str = NULL;
7557         guint8 type;
7558         guint8 flags;
7559
7560         if(parent_tree){
7561                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7562                                            "NT ACE: ");
7563                 tree = proto_item_add_subtree(item, ett_smb_ace);
7564         }
7565
7566         /* type */
7567         type = tvb_get_guint8(tvb, offset);
7568         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7569         offset += 1;
7570
7571         /* flags */
7572         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7573
7574         /* size */
7575         size = tvb_get_letohs(tvb, offset);
7576         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7577         offset += 2;
7578
7579         /* access mask */
7580         offset = dissect_nt_access_mask(
7581                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7582
7583         /* SID */
7584         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7585
7586         if (item)
7587                 proto_item_append_text(
7588                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7589                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7590
7591         g_free(sid_str);
7592
7593         proto_item_set_len(item, offset-old_offset);
7594
7595         /* Sometimes there is some spare space at the end of the ACE so use
7596            the size field to work out where the end is. */
7597
7598         return old_offset + size;
7599 }
7600
7601 static int
7602 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7603                proto_tree *parent_tree, char *drep, char *name,
7604                struct access_mask_info *ami)
7605 {
7606         proto_item *item = NULL;
7607         proto_tree *tree = NULL;
7608         int old_offset = offset;
7609         guint16 revision;
7610         guint32 num_aces;
7611
7612         if(parent_tree){
7613                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7614                                            "NT %s ACL", name);
7615                 tree = proto_item_add_subtree(item, ett_smb_acl);
7616         }
7617
7618         /* revision */
7619         revision = tvb_get_letohs(tvb, offset);
7620         proto_tree_add_uint(tree, hf_smb_acl_revision,
7621                 tvb, offset, 2, revision);
7622         offset += 2;
7623
7624         switch(revision){
7625         case 2:  /* only version we will ever see of this structure?*/
7626         case 3:
7627           /* size */
7628           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7629           offset += 2;
7630
7631           /* number of ace structures */
7632           num_aces = tvb_get_letohl(tvb, offset);
7633           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7634                               tvb, offset, 4, num_aces);
7635           offset += 4;
7636
7637           while(num_aces--){
7638             offset=dissect_nt_v2_ace(
7639                     tvb, offset, pinfo, tree, drep, ami);
7640           }
7641         }
7642
7643         proto_item_set_len(item, offset-old_offset);
7644         return offset;
7645 }
7646
7647 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7648   "OWNER is DEFAULTED",
7649   "Owner is NOT defaulted"
7650 };
7651 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7652   "GROUP is DEFAULTED",
7653   "Group is NOT defaulted"
7654 };
7655 static const true_false_string tfs_sec_desc_type_dacl_present = {
7656   "DACL is PRESENT",
7657   "DACL is NOT present"
7658 };
7659 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7660   "DACL is DEFAULTED",
7661   "DACL is NOT defaulted"
7662 };
7663 static const true_false_string tfs_sec_desc_type_sacl_present = {
7664   "SACL is PRESENT",
7665   "SACL is NOT present"
7666 };
7667 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7668   "SACL is DEFAULTED",
7669   "SACL is NOT defaulted"
7670 };
7671 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7672   "DACL has AUTO INHERIT REQUIRED",
7673   "DACL does NOT require auto inherit"
7674 };
7675 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7676   "SACL has AUTO INHERIT REQUIRED",
7677   "SACL does NOT require auto inherit"
7678 };
7679 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7680   "DACL is AUTO INHERITED",
7681   "DACL is NOT auto inherited"
7682 };
7683 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7684   "SACL is AUTO INHERITED",
7685   "SACL is NOT auto inherited"
7686 };
7687 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7688   "The DACL is PROTECTED",
7689   "The DACL is NOT protected"
7690 };
7691 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7692   "The SACL is PROTECTED",
7693   "The SACL is NOT protected"
7694 };
7695 static const true_false_string tfs_sec_desc_type_self_relative = {
7696   "This SecDesc is SELF RELATIVE",
7697   "This SecDesc is NOT self relative"
7698 };
7699
7700
7701 static int
7702 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7703 {
7704         proto_item *item = NULL;
7705         proto_tree *tree = NULL;
7706         guint16 mask;
7707
7708         mask = tvb_get_letohs(tvb, offset);
7709         if(parent_tree){
7710                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7711                                            "Type: 0x%04x", mask);
7712                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7713         }
7714
7715         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7716                                tvb, offset, 2, mask);
7717         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7718                                tvb, offset, 2, mask);
7719         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7720                                tvb, offset, 2, mask);
7721         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7722                                tvb, offset, 2, mask);
7723         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7724                                tvb, offset, 2, mask);
7725         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7726                                tvb, offset, 2, mask);
7727         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7728                                tvb, offset, 2, mask);
7729         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7730                                tvb, offset, 2, mask);
7731         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7732                                tvb, offset, 2, mask);
7733         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7734                                tvb, offset, 2, mask);
7735         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7736                                tvb, offset, 2, mask);
7737         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7738                                tvb, offset, 2, mask);
7739         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7740                                tvb, offset, 2, mask);
7741
7742
7743         offset += 2;
7744         return offset;
7745 }
7746
7747 int
7748 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7749                     proto_tree *parent_tree, char *drep, int len, 
7750                     struct access_mask_info *ami)
7751 {
7752         proto_item *item = NULL;
7753         proto_tree *tree = NULL;
7754         guint8 revision;
7755         int old_offset = offset;
7756         guint32 owner_sid_offset;
7757         guint32 group_sid_offset;
7758         guint32 sacl_offset;
7759         guint32 dacl_offset;
7760
7761         if(parent_tree){
7762                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7763                                            "NT Security Descriptor");
7764                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7765         }
7766
7767         /* revision */
7768         revision = tvb_get_guint8(tvb, offset);
7769         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7770                 tvb, offset, 1, revision);
7771         offset += 1;
7772
7773         /* next byte should be zero, for now just ignore it */
7774         offset += 1;
7775
7776
7777         switch(revision){
7778         case 1:  /* only version we will ever see of this structure?*/
7779           /* type */
7780           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7781
7782           /* offset to owner sid */
7783           owner_sid_offset = tvb_get_letohl(tvb, offset);
7784           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7785           offset += 4;
7786
7787           /* offset to group sid */
7788           group_sid_offset = tvb_get_letohl(tvb, offset);
7789           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7790           offset += 4;
7791
7792           /* offset to sacl */
7793           sacl_offset = tvb_get_letohl(tvb, offset);
7794           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7795           offset += 4;
7796
7797           /* offset to dacl */
7798           dacl_offset = tvb_get_letohl(tvb, offset);
7799           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7800           offset += 4;
7801
7802           /*owner SID*/
7803           if(owner_sid_offset){
7804             if (len == -1)
7805               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7806             else
7807               dissect_nt_sid(
7808                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7809           }
7810
7811           /*group SID*/
7812           if(group_sid_offset){
7813             dissect_nt_sid(
7814                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7815           }
7816
7817           /* sacl */
7818           if(sacl_offset){
7819             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7820                            drep, "System (SACL)", ami);
7821           }
7822
7823           /* dacl */
7824           if(dacl_offset){
7825             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7826                            drep, "User (DACL)", ami);
7827           }
7828
7829         }
7830
7831         return offset+len;
7832 }
7833
7834 static int
7835 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7836 {
7837         int old_offset, old_sid_offset;
7838         guint32 qsize;
7839
7840         do {
7841                 old_offset=offset;
7842
7843                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7844                 qsize=tvb_get_letohl(tvb, offset);
7845                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7846                 COUNT_BYTES_TRANS_SUBR(4);
7847
7848                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7849                 /* length of SID */
7850                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7851                 COUNT_BYTES_TRANS_SUBR(4);
7852
7853                 /* 16 unknown bytes */
7854                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7855                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7856                             offset, 8, TRUE);
7857                 COUNT_BYTES_TRANS_SUBR(8);
7858
7859                 /* number of bytes for used quota */
7860                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7861                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7862                 COUNT_BYTES_TRANS_SUBR(8);
7863
7864                 /* number of bytes for quota warning */
7865                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7866                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7867                 COUNT_BYTES_TRANS_SUBR(8);
7868
7869                 /* number of bytes for quota limit */
7870                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7871                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7872                 COUNT_BYTES_TRANS_SUBR(8);
7873
7874                 /* SID of the user */
7875                 old_sid_offset=offset;
7876                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7877                 *bcp -= (offset-old_sid_offset);
7878
7879                 if(qsize){
7880                         offset = old_offset+qsize;
7881                 }
7882         }while(qsize);
7883
7884
7885         return offset;
7886 }
7887
7888
7889 static int
7890 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7891 {
7892         proto_item *item = NULL;
7893         proto_tree *tree = NULL;
7894         smb_info_t *si;
7895         int old_offset = offset;
7896         guint16 bcp=bc; /* XXX fixme */
7897
7898         si = (smb_info_t *)pinfo->private_data;
7899
7900         if(parent_tree){
7901                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7902                                 "%s Data",
7903                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7904                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7905         }
7906
7907         switch(ntd->subcmd){
7908         case NT_TRANS_CREATE:
7909                 /* security descriptor */
7910                 if(ntd->sd_len){
7911                         offset = dissect_nt_sec_desc(
7912                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
7913                                 NULL);
7914                 }
7915
7916                 /* extended attributes */
7917                 if(ntd->ea_len){
7918                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7919                         offset += ntd->ea_len;
7920                 }
7921
7922                 break;
7923         case NT_TRANS_IOCTL:
7924                 /* ioctl data */
7925                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7926                 offset += bc;
7927
7928                 break;
7929         case NT_TRANS_SSD:
7930                 offset = dissect_nt_sec_desc(
7931                         tvb, offset, pinfo, tree, NULL, bc, NULL);
7932                 break;
7933         case NT_TRANS_NOTIFY:
7934                 break;
7935         case NT_TRANS_RENAME:
7936                 /* XXX not documented */
7937                 break;
7938         case NT_TRANS_QSD:
7939                 break;
7940         case NT_TRANS_GET_USER_QUOTA:
7941                 /* unknown 4 bytes */
7942                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7943                             offset, 4, TRUE);
7944                 offset += 4;
7945
7946                 /* length of SID */
7947                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7948                 offset +=4;
7949
7950                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7951                 break;
7952         case NT_TRANS_SET_USER_QUOTA:
7953                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7954                 break;
7955         }
7956
7957         /* ooops there were data we didnt know how to process */
7958         if((offset-old_offset) < bc){
7959                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7960                     bc - (offset-old_offset), TRUE);
7961                 offset += bc - (offset-old_offset);
7962         }
7963
7964         return offset;
7965 }
7966
7967 static int
7968 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)
7969 {
7970         proto_item *item = NULL;
7971         proto_tree *tree = NULL;
7972         smb_info_t *si;
7973         guint32 fn_len;
7974         const char *fn;
7975
7976         si = (smb_info_t *)pinfo->private_data;
7977
7978         if(parent_tree){
7979                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7980                                 "%s Parameters",
7981                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7982                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7983         }
7984
7985         switch(ntd->subcmd){
7986         case NT_TRANS_CREATE:
7987                 /* Create flags */
7988                 offset = dissect_nt_create_bits(tvb, tree, offset);
7989                 bc -= 4;
7990
7991                 /* root directory fid */
7992                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7993                 COUNT_BYTES(4);
7994
7995                 /* nt access mask */
7996                 offset = dissect_smb_access_mask(tvb, tree, offset);
7997                 bc -= 4;
7998
7999                 /* allocation size */
8000                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8001                 COUNT_BYTES(8);
8002
8003                 /* Extended File Attributes */
8004                 offset = dissect_file_ext_attr(tvb, tree, offset);
8005                 bc -= 4;
8006
8007                 /* share access */
8008                 offset = dissect_nt_share_access(tvb, tree, offset);
8009                 bc -= 4;
8010
8011                 /* create disposition */
8012                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8013                 COUNT_BYTES(4);
8014
8015                 /* create options */
8016                 offset = dissect_nt_create_options(tvb, tree, offset);
8017                 bc -= 4;
8018
8019                 /* sd length */
8020                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8021                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8022                 COUNT_BYTES(4);
8023
8024                 /* ea length */
8025                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8026                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8027                 COUNT_BYTES(4);
8028
8029                 /* file name len */
8030                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8031                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8032                 COUNT_BYTES(4);
8033
8034                 /* impersonation level */
8035                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8036                 COUNT_BYTES(4);
8037
8038                 /* security flags */
8039                 offset = dissect_nt_security_flags(tvb, tree, offset);
8040                 bc -= 1;
8041
8042                 /* file name */
8043                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8044                 if (fn != NULL) {
8045                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8046                                 fn);
8047                         COUNT_BYTES(fn_len);
8048                 }
8049
8050                 break;
8051         case NT_TRANS_IOCTL:
8052                 break;
8053         case NT_TRANS_SSD: {
8054                 guint16 fid;
8055
8056                 /* fid */
8057                 fid = tvb_get_letohs(tvb, offset);
8058                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8059                 offset += 2;
8060
8061                 /* 2 reserved bytes */
8062                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8063                 offset += 2;
8064
8065                 /* security information */
8066                 offset = dissect_security_information_mask(tvb, tree, offset);
8067                 break;
8068         }
8069         case NT_TRANS_NOTIFY:
8070                 break;
8071         case NT_TRANS_RENAME:
8072                 /* XXX not documented */
8073                 break;
8074         case NT_TRANS_QSD: {
8075                 guint16 fid;
8076
8077                 /* fid */
8078                 fid = tvb_get_letohs(tvb, offset);
8079                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8080                 offset += 2;
8081
8082                 /* 2 reserved bytes */
8083                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8084                 offset += 2;
8085
8086                 /* security information */
8087                 offset = dissect_security_information_mask(tvb, tree, offset);
8088                 break;
8089         }
8090         case NT_TRANS_GET_USER_QUOTA:
8091                 /* not decoded yet */
8092                 break;
8093         case NT_TRANS_SET_USER_QUOTA:
8094                 /* not decoded yet */
8095                 break;
8096         }
8097
8098         return offset;
8099 }
8100
8101 static int
8102 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8103 {
8104         proto_item *item = NULL;
8105         proto_tree *tree = NULL;
8106         smb_info_t *si;
8107         int old_offset = offset;
8108
8109         si = (smb_info_t *)pinfo->private_data;
8110
8111         if(parent_tree){
8112                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8113                                 "%s Setup",
8114                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8115                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8116         }
8117
8118         switch(ntd->subcmd){
8119         case NT_TRANS_CREATE:
8120                 break;
8121         case NT_TRANS_IOCTL: {
8122                 guint16 fid;
8123
8124                 /* function code */
8125                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8126                 offset += 4;
8127
8128                 /* fid */
8129                 fid = tvb_get_letohs(tvb, offset);
8130                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8131                 offset += 2;
8132
8133                 /* isfsctl */
8134                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8135                 offset += 1;
8136
8137                 /* isflags */
8138                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8139
8140                 break;
8141         }
8142         case NT_TRANS_SSD:
8143                 break;
8144         case NT_TRANS_NOTIFY: {
8145                 guint16 fid;
8146
8147                 /* completion filter */
8148                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8149
8150                 /* fid */
8151                 fid = tvb_get_letohs(tvb, offset);
8152                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8153                 offset += 2;
8154
8155                 /* watch tree */
8156                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8157                 offset += 1;
8158
8159                 /* reserved byte */
8160                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8161                 offset += 1;
8162
8163                 break;
8164         }
8165         case NT_TRANS_RENAME:
8166                 /* XXX not documented */
8167                 break;
8168         case NT_TRANS_QSD:
8169                 break;
8170         case NT_TRANS_GET_USER_QUOTA:
8171                 /* not decoded yet */
8172                 break;
8173         case NT_TRANS_SET_USER_QUOTA:
8174                 /* not decoded yet */
8175                 break;
8176         }
8177
8178         return old_offset+len;
8179 }
8180
8181
8182 static int
8183 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8184 {
8185         guint8 wc, sc;
8186         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8187         smb_info_t *si;
8188         smb_saved_info_t *sip;
8189         int subcmd;
8190         nt_trans_data ntd;
8191         guint16 bc;
8192         int padcnt;
8193         smb_nt_transact_info_t *nti;
8194
8195         si = (smb_info_t *)pinfo->private_data;
8196         sip = si->sip;
8197
8198         WORD_COUNT;
8199
8200         if(wc>=19){
8201                 /* primary request */
8202                 /* max setup count */
8203                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8204                 offset += 1;
8205
8206                 /* 2 reserved bytes */
8207                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8208                 offset += 2;
8209         } else {
8210                 /* secondary request */
8211                 /* 3 reserved bytes */
8212                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8213                 offset += 3;
8214         }
8215
8216
8217         /* total param count */
8218         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8219         offset += 4;
8220
8221         /* total data count */
8222         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8223         offset += 4;
8224
8225         if(wc>=19){
8226                 /* primary request */
8227                 /* max param count */
8228                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8229                 offset += 4;
8230
8231                 /* max data count */
8232                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8233                 offset += 4;
8234         }
8235
8236         /* param count */
8237         pc = tvb_get_letohl(tvb, offset);
8238         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8239         offset += 4;
8240
8241         /* param offset */
8242         po = tvb_get_letohl(tvb, offset);
8243         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8244         offset += 4;
8245
8246         /* param displacement */
8247         if(wc>=19){
8248                 /* primary request*/
8249                 pd = 0;
8250         } else {
8251                 /* secondary request */
8252                 pd = tvb_get_letohl(tvb, offset);
8253                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8254                 offset += 4;
8255         }
8256
8257         /* data count */
8258         dc = tvb_get_letohl(tvb, offset);
8259         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8260         offset += 4;
8261
8262         /* data offset */
8263         od = tvb_get_letohl(tvb, offset);
8264         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8265         offset += 4;
8266
8267         /* data displacement */
8268         if(wc>=19){
8269                 /* primary request */
8270                 dd = 0;
8271         } else {
8272                 /* secondary request */
8273                 dd = tvb_get_letohl(tvb, offset);
8274                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8275                 offset += 4;
8276         }
8277
8278         /* setup count */
8279         if(wc>=19){
8280                 /* primary request */
8281                 sc = tvb_get_guint8(tvb, offset);
8282                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8283                 offset += 1;
8284         } else {
8285                 /* secondary request */
8286                 sc = 0;
8287         }
8288
8289         /* function */
8290         if(wc>=19){
8291                 /* primary request */
8292                 subcmd = tvb_get_letohs(tvb, offset);
8293                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8294                 if(check_col(pinfo->cinfo, COL_INFO)){
8295                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8296                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8297                 }
8298                 ntd.subcmd = subcmd;
8299                 if (!si->unidir) {
8300                         if(!pinfo->fd->flags.visited){
8301                                 /*
8302                                  * Allocate a new smb_nt_transact_info_t
8303                                  * structure.
8304                                  */
8305                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8306                                 nti->subcmd = subcmd;
8307                                 sip->extra_info = nti;
8308                         }
8309                 }
8310         } else {
8311                 /* secondary request */
8312                 if(check_col(pinfo->cinfo, COL_INFO)){
8313                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8314                 }
8315         }
8316         offset += 2;
8317
8318         /* this is a padding byte */
8319         if(offset%1){
8320                 /* pad byte */
8321                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8322                 offset += 1;
8323         }
8324
8325         /* if there were any setup bytes, decode them */
8326         if(sc){
8327                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8328                 offset += sc*2;
8329         }
8330
8331         BYTE_COUNT;
8332
8333         /* parameters */
8334         if(po>(guint32)offset){
8335                 /* We have some initial padding bytes.
8336                 */
8337                 padcnt = po-offset;
8338                 if (padcnt > bc)
8339                         padcnt = bc;
8340                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8341                 COUNT_BYTES(padcnt);
8342         }
8343         if(pc){
8344                 CHECK_BYTE_COUNT(pc);
8345                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8346                 COUNT_BYTES(pc);
8347         }
8348
8349         /* data */
8350         if(od>(guint32)offset){
8351                 /* We have some initial padding bytes.
8352                 */
8353                 padcnt = od-offset;
8354                 if (padcnt > bc)
8355                         padcnt = bc;
8356                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8357                 COUNT_BYTES(padcnt);
8358         }
8359         if(dc){
8360                 CHECK_BYTE_COUNT(dc);
8361                 dissect_nt_trans_data_request(
8362                         tvb, pinfo, offset, tree, dc, &ntd);
8363                 COUNT_BYTES(dc);
8364         }
8365
8366         END_OF_SMB
8367
8368         return offset;
8369 }
8370
8371
8372
8373 static int
8374 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8375                                int offset, proto_tree *parent_tree, int len,
8376                                nt_trans_data *ntd _U_)
8377 {
8378         proto_item *item = NULL;
8379         proto_tree *tree = NULL;
8380         smb_info_t *si;
8381         smb_nt_transact_info_t *nti;
8382         guint16 bcp;
8383
8384         si = (smb_info_t *)pinfo->private_data;
8385         if (si->sip != NULL)
8386                 nti = si->sip->extra_info;
8387         else
8388                 nti = NULL;
8389
8390         if(parent_tree){
8391                 if(nti != NULL){
8392                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8393                                 "%s Data",
8394                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8395                 } else {
8396                         /*
8397                          * We never saw the request to which this is a
8398                          * response.
8399                          */
8400                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8401                                 "Unknown NT Transaction Data (matching request not seen)");
8402                 }
8403                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8404         }
8405
8406         if (nti == NULL) {
8407                 offset += len;
8408                 return offset;
8409         }
8410         switch(nti->subcmd){
8411         case NT_TRANS_CREATE:
8412                 break;
8413         case NT_TRANS_IOCTL:
8414                 /* ioctl data */
8415                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8416                 offset += len;
8417
8418                 break;
8419         case NT_TRANS_SSD:
8420                 break;
8421         case NT_TRANS_NOTIFY:
8422                 break;
8423         case NT_TRANS_RENAME:
8424                 /* XXX not documented */
8425                 break;
8426         case NT_TRANS_QSD: {
8427                 /*
8428                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8429                  * which may be documented in the Win32 documentation
8430                  * somewhere.
8431                  */
8432                 offset = dissect_nt_sec_desc(
8433                         tvb, offset, pinfo, tree, NULL, len, NULL);
8434                 break;
8435         }
8436         case NT_TRANS_GET_USER_QUOTA:
8437                 bcp=len;
8438                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8439                 break;
8440         case NT_TRANS_SET_USER_QUOTA:
8441                 /* not decoded yet */
8442                 break;
8443         }
8444
8445         return offset;
8446 }
8447
8448 static int
8449 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8450                                 int offset, proto_tree *parent_tree,
8451                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8452 {
8453         proto_item *item = NULL;
8454         proto_tree *tree = NULL;
8455         guint32 fn_len;
8456         const char *fn;
8457         smb_info_t *si;
8458         smb_nt_transact_info_t *nti;
8459         guint16 fid;
8460         int old_offset;
8461         guint32 neo;
8462         int padcnt;
8463
8464         si = (smb_info_t *)pinfo->private_data;
8465         if (si->sip != NULL)
8466                 nti = si->sip->extra_info;
8467         else
8468                 nti = NULL;
8469
8470         if(parent_tree){
8471                 if(nti != NULL){
8472                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8473                                 "%s Parameters",
8474                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8475                 } else {
8476                         /*
8477                          * We never saw the request to which this is a
8478                          * response.
8479                          */
8480                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8481                                 "Unknown NT Transaction Parameters (matching request not seen)");
8482                 }
8483                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8484         }
8485
8486         if (nti == NULL) {
8487                 offset += len;
8488                 return offset;
8489         }
8490         switch(nti->subcmd){
8491         case NT_TRANS_CREATE:
8492                 /* oplock level */
8493                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8494                 offset += 1;
8495
8496                 /* reserved byte */
8497                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8498                 offset += 1;
8499
8500                 /* fid */
8501                 fid = tvb_get_letohs(tvb, offset);
8502                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8503                 offset += 2;
8504
8505                 /* create action */
8506                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8507                 offset += 4;
8508
8509                 /* ea error offset */
8510                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8511                 offset += 4;
8512
8513                 /* create time */
8514                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8515                         hf_smb_create_time);
8516
8517                 /* access time */
8518                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8519                         hf_smb_access_time);
8520
8521                 /* last write time */
8522                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8523                         hf_smb_last_write_time);
8524
8525                 /* last change time */
8526                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8527                         hf_smb_change_time);
8528
8529                 /* Extended File Attributes */
8530                 offset = dissect_file_ext_attr(tvb, tree, offset);
8531
8532                 /* allocation size */
8533                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8534                 offset += 8;
8535
8536                 /* end of file */
8537                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8538                 offset += 8;
8539
8540                 /* File Type */
8541                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8542                 offset += 2;
8543
8544                 /* device state */
8545                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8546
8547                 /* is directory */
8548                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8549                 offset += 1;
8550                 break;
8551         case NT_TRANS_IOCTL:
8552                 break;
8553         case NT_TRANS_SSD:
8554                 break;
8555         case NT_TRANS_NOTIFY:
8556                 while(len){
8557                         old_offset = offset;
8558
8559                         /* next entry offset */
8560                         neo = tvb_get_letohl(tvb, offset);
8561                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8562                         COUNT_BYTES(4);
8563                         len -= 4;
8564                         /* broken implementations */
8565                         if(len<0)break;
8566
8567                         /* action */
8568                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8569                         COUNT_BYTES(4);
8570                         len -= 4;
8571                         /* broken implementations */
8572                         if(len<0)break;
8573
8574                         /* file name len */
8575                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8576                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8577                         COUNT_BYTES(4);
8578                         len -= 4;
8579                         /* broken implementations */
8580                         if(len<0)break;
8581
8582                         /* file name */
8583                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8584                         if (fn == NULL)
8585                                 break;
8586                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8587                                 fn);
8588                         COUNT_BYTES(fn_len);
8589                         len -= fn_len;
8590                         /* broken implementations */
8591                         if(len<0)break;
8592
8593                         if (neo == 0)
8594                                 break;  /* no more structures */
8595
8596                         /* skip to next structure */
8597                         padcnt = (old_offset + neo) - offset;
8598                         if (padcnt < 0) {
8599                                 /*
8600                                  * XXX - this is bogus; flag it?
8601                                  */
8602                                 padcnt = 0;
8603                         }
8604                         if (padcnt != 0) {
8605                                 COUNT_BYTES(padcnt);
8606                                 len -= padcnt;
8607                                 /* broken implementations */
8608                                 if(len<0)break;
8609                         }
8610                 }
8611                 break;
8612         case NT_TRANS_RENAME:
8613                 /* XXX not documented */
8614                 break;
8615         case NT_TRANS_QSD:
8616                 /*
8617                  * This appears to be the size of the security
8618                  * descriptor; the calling sequence of
8619                  * "ZwQuerySecurityObject()" suggests that it would
8620                  * be.  The actual security descriptor wouldn't
8621                  * follow if the max data count in the request
8622                  * was smaller; this lets the client know how
8623                  * big a buffer it needs to provide.
8624                  */
8625                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8626                 offset += 4;
8627                 break;
8628         case NT_TRANS_GET_USER_QUOTA:
8629                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8630                         tvb_get_letohl(tvb, offset));
8631                 offset += 4;
8632                 break;
8633         case NT_TRANS_SET_USER_QUOTA:
8634                 /* not decoded yet */
8635                 break;
8636         }
8637
8638         return offset;
8639 }
8640
8641 static int
8642 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8643                                 int offset, proto_tree *parent_tree,
8644                                 int len, nt_trans_data *ntd _U_)
8645 {
8646         proto_item *item = NULL;
8647         proto_tree *tree = NULL;
8648         smb_info_t *si;
8649         smb_nt_transact_info_t *nti;
8650
8651         si = (smb_info_t *)pinfo->private_data;
8652         if (si->sip != NULL)
8653                 nti = si->sip->extra_info;
8654         else
8655                 nti = NULL;
8656
8657         if(parent_tree){
8658                 if(nti != NULL){
8659                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8660                                 "%s Setup",
8661                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8662                 } else {
8663                         /*
8664                          * We never saw the request to which this is a
8665                          * response.
8666                          */
8667                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8668                                 "Unknown NT Transaction Setup (matching request not seen)");
8669                 }
8670                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8671         }
8672
8673         if (nti == NULL) {
8674                 offset += len;
8675                 return offset;
8676         }
8677         switch(nti->subcmd){
8678         case NT_TRANS_CREATE:
8679                 break;
8680         case NT_TRANS_IOCTL:
8681                 break;
8682         case NT_TRANS_SSD:
8683                 break;
8684         case NT_TRANS_NOTIFY:
8685                 break;
8686         case NT_TRANS_RENAME:
8687                 /* XXX not documented */
8688                 break;
8689         case NT_TRANS_QSD:
8690                 break;
8691         case NT_TRANS_GET_USER_QUOTA:
8692                 /* not decoded yet */
8693                 break;
8694         case NT_TRANS_SET_USER_QUOTA:
8695                 /* not decoded yet */
8696                 break;
8697         }
8698
8699         return offset;
8700 }
8701
8702 static int
8703 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8704 {
8705         guint8 wc, sc;
8706         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8707         guint32 td=0, tp=0;
8708         smb_info_t *si;
8709         smb_nt_transact_info_t *nti;
8710         static nt_trans_data ntd;
8711         guint16 bc;
8712         int padcnt;
8713         fragment_data *r_fd = NULL;
8714         tvbuff_t *pd_tvb=NULL;
8715         gboolean save_fragmented;
8716
8717         si = (smb_info_t *)pinfo->private_data;
8718         if (si->sip != NULL)
8719                 nti = si->sip->extra_info;
8720         else
8721                 nti = NULL;
8722
8723         /* primary request */
8724         if(nti != NULL){
8725                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8726                 if(check_col(pinfo->cinfo, COL_INFO)){
8727                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8728                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8729                 }
8730         } else {
8731                 proto_tree_add_text(tree, tvb, offset, 0,
8732                         "Function: <unknown function - could not find matching request>");
8733                 if(check_col(pinfo->cinfo, COL_INFO)){
8734                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8735                 }
8736         }
8737
8738         WORD_COUNT;
8739
8740         /* 3 reserved bytes */
8741         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8742         offset += 3;
8743
8744         /* total param count */
8745         tp = tvb_get_letohl(tvb, offset);
8746         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8747         offset += 4;
8748
8749         /* total data count */
8750         td = tvb_get_letohl(tvb, offset);
8751         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8752         offset += 4;
8753
8754         /* param count */
8755         pc = tvb_get_letohl(tvb, offset);
8756         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8757         offset += 4;
8758
8759         /* param offset */
8760         po = tvb_get_letohl(tvb, offset);
8761         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8762         offset += 4;
8763
8764         /* param displacement */
8765         pd = tvb_get_letohl(tvb, offset);
8766         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8767         offset += 4;
8768
8769         /* data count */
8770         dc = tvb_get_letohl(tvb, offset);
8771         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8772         offset += 4;
8773
8774         /* data offset */
8775         od = tvb_get_letohl(tvb, offset);
8776         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8777         offset += 4;
8778
8779         /* data displacement */
8780         dd = tvb_get_letohl(tvb, offset);
8781         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8782         offset += 4;
8783
8784         /* setup count */
8785         sc = tvb_get_guint8(tvb, offset);
8786         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8787         offset += 1;
8788
8789         /* setup data */
8790         if(sc){
8791                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8792                 offset += sc*2;
8793         }
8794
8795         BYTE_COUNT;
8796
8797         /* reassembly of SMB NT Transaction data payload.
8798            In this section we do reassembly of both the data and parameters
8799            blocks of the SMB transaction command.
8800         */
8801         save_fragmented = pinfo->fragmented;
8802         /* do we need reassembly? */
8803         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8804                 /* oh yeah, either data or parameter section needs
8805                    reassembly...
8806                 */
8807                 pinfo->fragmented = TRUE;
8808                 if(smb_trans_reassembly){
8809                         /* ...and we were told to do reassembly */
8810                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8811                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8812                                                              po, pc, pd, td+tp);
8813
8814                         }
8815                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8816                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8817                                                              od, dc, dd+tp, td+tp);
8818                         }
8819                 }
8820         }
8821
8822         /* if we got a reassembled fd structure from the reassembly routine we
8823            must create pd_tvb from it
8824         */
8825         if(r_fd){
8826                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8827                                              r_fd->datalen);
8828                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8829                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8830
8831                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8832         }
8833
8834
8835         if(pd_tvb){
8836           /* we have reassembled data, grab param and data from there */
8837           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8838                                           &ntd, tvb_length(pd_tvb));
8839           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8840         } else {
8841           /* we do not have reassembled data, just use what we have in the
8842              packet as well as we can */
8843           /* parameters */
8844           if(po>(guint32)offset){
8845             /* We have some initial padding bytes.
8846              */
8847             padcnt = po-offset;
8848             if (padcnt > bc)
8849               padcnt = bc;
8850             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8851             COUNT_BYTES(padcnt);
8852           }
8853           if(pc){
8854             CHECK_BYTE_COUNT(pc);
8855             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8856             COUNT_BYTES(pc);
8857           }
8858
8859           /* data */
8860           if(od>(guint32)offset){
8861             /* We have some initial padding bytes.
8862              */
8863             padcnt = od-offset;
8864             if (padcnt > bc)
8865               padcnt = bc;
8866             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8867             COUNT_BYTES(padcnt);
8868           }
8869           if(dc){
8870             CHECK_BYTE_COUNT(dc);
8871             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8872             COUNT_BYTES(dc);
8873           }
8874         }
8875         pinfo->fragmented = save_fragmented;
8876
8877         END_OF_SMB
8878
8879         return offset;
8880 }
8881
8882 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8883    NT Transaction command  ends here
8884    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8885
8886 static const value_string print_mode_vals[] = {
8887         {0,     "Text Mode"},
8888         {1,     "Graphics Mode"},
8889         {0, NULL}
8890 };
8891
8892 static int
8893 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8894 {
8895         smb_info_t *si = pinfo->private_data;
8896         int fn_len;
8897         const char *fn;
8898         guint8 wc;
8899         guint16 bc;
8900
8901         WORD_COUNT;
8902
8903         /* setup len */
8904         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8905         offset += 2;
8906
8907         /* print mode */
8908         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8909         offset += 2;
8910
8911         BYTE_COUNT;
8912
8913         /* buffer format */
8914         CHECK_BYTE_COUNT(1);
8915         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8916         COUNT_BYTES(1);
8917
8918         /* print identifier */
8919         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8920         if (fn == NULL)
8921                 goto endofcommand;
8922         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8923                 fn);
8924         COUNT_BYTES(fn_len);
8925
8926         END_OF_SMB
8927
8928         return offset;
8929 }
8930
8931
8932 static int
8933 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8934 {
8935         int cnt;
8936         guint8 wc;
8937         guint16 bc, fid;
8938
8939         WORD_COUNT;
8940
8941         /* fid */
8942         fid = tvb_get_letohs(tvb, offset);
8943         add_fid(tvb, pinfo, tree, offset, 2, fid);
8944         offset += 2;
8945
8946         BYTE_COUNT;
8947
8948         /* buffer format */
8949         CHECK_BYTE_COUNT(1);
8950         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8951         COUNT_BYTES(1);
8952
8953         /* data len */
8954         CHECK_BYTE_COUNT(2);
8955         cnt = tvb_get_letohs(tvb, offset);
8956         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8957         COUNT_BYTES(2);
8958
8959         /* file data */
8960         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8961
8962         END_OF_SMB
8963
8964         return offset;
8965 }
8966
8967
8968 static const value_string print_status_vals[] = {
8969         {1,     "Held or Stopped"},
8970         {2,     "Printing"},
8971         {3,     "Awaiting print"},
8972         {4,     "In intercept"},
8973         {5,     "File had error"},
8974         {6,     "Printer error"},
8975         {0, NULL}
8976 };
8977
8978 static int
8979 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8980 {
8981         guint8 wc;
8982         guint16 bc;
8983
8984         WORD_COUNT;
8985
8986         /* max count */
8987         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8988         offset += 2;
8989
8990         /* start index */
8991         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8992         offset += 2;
8993
8994         BYTE_COUNT;
8995
8996         END_OF_SMB
8997
8998         return offset;
8999 }
9000
9001 static int
9002 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9003     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9004 {
9005         proto_item *item = NULL;
9006         proto_tree *tree = NULL;
9007         smb_info_t *si = pinfo->private_data;
9008         int fn_len;
9009         const char *fn;
9010
9011         if(parent_tree){
9012                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9013                         "Queue entry");
9014                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9015         }
9016
9017         /* queued time */
9018         CHECK_BYTE_COUNT_SUBR(4);
9019         offset = dissect_smb_datetime(tvb, tree, offset,
9020                 hf_smb_print_queue_date,
9021                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9022         *bcp -= 4;
9023
9024         /* status */
9025         CHECK_BYTE_COUNT_SUBR(1);
9026         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9027         COUNT_BYTES_SUBR(1);
9028
9029         /* spool file number */
9030         CHECK_BYTE_COUNT_SUBR(2);
9031         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9032         COUNT_BYTES_SUBR(2);
9033
9034         /* spool file size */
9035         CHECK_BYTE_COUNT_SUBR(4);
9036         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9037         COUNT_BYTES_SUBR(4);
9038
9039         /* reserved byte */
9040         CHECK_BYTE_COUNT_SUBR(1);
9041         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9042         COUNT_BYTES_SUBR(1);
9043
9044         /* file name */
9045         fn_len = 16;
9046         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9047         CHECK_STRING_SUBR(fn);
9048         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9049                 fn);
9050         COUNT_BYTES_SUBR(fn_len);
9051
9052         *trunc = FALSE;
9053         return offset;
9054 }
9055
9056 static int
9057 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9058 {
9059         guint16 cnt=0, len;
9060         guint8 wc;
9061         guint16 bc;
9062         gboolean trunc;
9063
9064         WORD_COUNT;
9065
9066         /* count */
9067         cnt = tvb_get_letohs(tvb, offset);
9068         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9069         offset += 2;
9070
9071         /* restart index */
9072         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9073         offset += 2;
9074
9075         BYTE_COUNT;
9076
9077         /* buffer format */
9078         CHECK_BYTE_COUNT(1);
9079         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9080         COUNT_BYTES(1);
9081
9082         /* data len */
9083         CHECK_BYTE_COUNT(2);
9084         len = tvb_get_letohs(tvb, offset);
9085         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9086         COUNT_BYTES(2);
9087
9088         /* queue elements */
9089         while(cnt--){
9090                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9091                     &bc, &trunc);
9092                 if (trunc)
9093                         goto endofcommand;
9094         }
9095
9096         END_OF_SMB
9097
9098         return offset;
9099 }
9100
9101
9102 static int
9103 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9104 {
9105         int name_len;
9106         guint16 bc;
9107         guint8 wc;
9108         guint16 message_len;
9109
9110         WORD_COUNT;
9111
9112         BYTE_COUNT;
9113
9114         /* buffer format */
9115         CHECK_BYTE_COUNT(1);
9116         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9117         COUNT_BYTES(1);
9118
9119         /* originator name */
9120         /* XXX - what if this runs past bc? */
9121         name_len = tvb_strsize(tvb, offset);
9122         CHECK_BYTE_COUNT(name_len);
9123         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9124             name_len, TRUE);
9125         COUNT_BYTES(name_len);
9126
9127         /* buffer format */
9128         CHECK_BYTE_COUNT(1);
9129         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9130         COUNT_BYTES(1);
9131
9132         /* destination name */
9133         /* XXX - what if this runs past bc? */
9134         name_len = tvb_strsize(tvb, offset);
9135         CHECK_BYTE_COUNT(name_len);
9136         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9137             name_len, TRUE);
9138         COUNT_BYTES(name_len);
9139
9140         /* buffer format */
9141         CHECK_BYTE_COUNT(1);
9142         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9143         COUNT_BYTES(1);
9144
9145         /* message len */
9146         CHECK_BYTE_COUNT(2);
9147         message_len = tvb_get_letohs(tvb, offset);
9148         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9149             message_len);
9150         COUNT_BYTES(2);
9151
9152         /* message */
9153         CHECK_BYTE_COUNT(message_len);
9154         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9155             TRUE);
9156         COUNT_BYTES(message_len);
9157
9158         END_OF_SMB
9159
9160         return offset;
9161 }
9162
9163 static int
9164 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9165 {
9166         int name_len;
9167         guint16 bc;
9168         guint8 wc;
9169
9170         WORD_COUNT;
9171
9172         BYTE_COUNT;
9173
9174         /* buffer format */
9175         CHECK_BYTE_COUNT(1);
9176         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9177         COUNT_BYTES(1);
9178
9179         /* originator name */
9180         /* XXX - what if this runs past bc? */
9181         name_len = tvb_strsize(tvb, offset);
9182         CHECK_BYTE_COUNT(name_len);
9183         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9184             name_len, TRUE);
9185         COUNT_BYTES(name_len);
9186
9187         /* buffer format */
9188         CHECK_BYTE_COUNT(1);
9189         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9190         COUNT_BYTES(1);
9191
9192         /* destination name */
9193         /* XXX - what if this runs past bc? */
9194         name_len = tvb_strsize(tvb, offset);
9195         CHECK_BYTE_COUNT(name_len);
9196         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9197             name_len, TRUE);
9198         COUNT_BYTES(name_len);
9199
9200         END_OF_SMB
9201
9202         return offset;
9203 }
9204
9205 static int
9206 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9207 {
9208         guint16 bc;
9209         guint8 wc;
9210
9211         WORD_COUNT;
9212
9213         /* message group ID */
9214         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9215         offset += 2;
9216
9217         BYTE_COUNT;
9218
9219         END_OF_SMB
9220
9221         return offset;
9222 }
9223
9224 static int
9225 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9226 {
9227         guint16 bc;
9228         guint8 wc;
9229         guint16 message_len;
9230
9231         WORD_COUNT;
9232
9233         BYTE_COUNT;
9234
9235         /* buffer format */
9236         CHECK_BYTE_COUNT(1);
9237         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9238         COUNT_BYTES(1);
9239
9240         /* message len */
9241         CHECK_BYTE_COUNT(2);
9242         message_len = tvb_get_letohs(tvb, offset);
9243         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9244             message_len);
9245         COUNT_BYTES(2);
9246
9247         /* message */
9248         CHECK_BYTE_COUNT(message_len);
9249         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9250             TRUE);
9251         COUNT_BYTES(message_len);
9252
9253         END_OF_SMB
9254
9255         return offset;
9256 }
9257
9258 static int
9259 dissect_forwarded_name(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         /* forwarded 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_forwarded_name, tvb, offset,
9279             name_len, TRUE);
9280         COUNT_BYTES(name_len);
9281
9282         END_OF_SMB
9283
9284         return offset;
9285 }
9286
9287 static int
9288 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9289 {
9290         int name_len;
9291         guint16 bc;
9292         guint8 wc;
9293
9294         WORD_COUNT;
9295
9296         BYTE_COUNT;
9297
9298         /* buffer format */
9299         CHECK_BYTE_COUNT(1);
9300         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9301         COUNT_BYTES(1);
9302
9303         /* machine name */
9304         /* XXX - what if this runs past bc? */
9305         name_len = tvb_strsize(tvb, offset);
9306         CHECK_BYTE_COUNT(name_len);
9307         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9308             name_len, TRUE);
9309         COUNT_BYTES(name_len);
9310
9311         END_OF_SMB
9312
9313         return offset;
9314 }
9315
9316
9317 static int
9318 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9319 {
9320         guint8  wc, cmd=0xff;
9321         guint16 andxoffset=0;
9322         guint16 bc;
9323         smb_info_t *si = pinfo->private_data;
9324         int fn_len;
9325         const char *fn;
9326
9327         WORD_COUNT;
9328
9329         /* next smb command */
9330         cmd = tvb_get_guint8(tvb, offset);
9331         if(cmd!=0xff){
9332                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9333         } else {
9334                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
9335         }
9336         offset += 1;
9337
9338         /* reserved byte */
9339         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9340         offset += 1;
9341
9342         /* andxoffset */
9343         andxoffset = tvb_get_letohs(tvb, offset);
9344         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9345         offset += 2;
9346
9347         /* reserved byte */
9348         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9349         offset += 1;
9350
9351         /* file name len */
9352         fn_len = tvb_get_letohs(tvb, offset);
9353         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9354         offset += 2;
9355
9356         /* Create flags */
9357         offset = dissect_nt_create_bits(tvb, tree, offset);
9358
9359         /* root directory fid */
9360         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9361         offset += 4;
9362
9363         /* nt access mask */
9364         offset = dissect_smb_access_mask(tvb, tree, offset);
9365
9366         /* allocation size */
9367         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9368         offset += 8;
9369
9370         /* Extended File Attributes */
9371         offset = dissect_file_ext_attr(tvb, tree, offset);
9372
9373         /* share access */
9374         offset = dissect_nt_share_access(tvb, tree, offset);
9375
9376         /* create disposition */
9377         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9378         offset += 4;
9379
9380         /* create options */
9381         offset = dissect_nt_create_options(tvb, tree, offset);
9382
9383         /* impersonation level */
9384         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9385         offset += 4;
9386
9387         /* security flags */
9388         offset = dissect_nt_security_flags(tvb, tree, offset);
9389
9390         BYTE_COUNT;
9391
9392         /* file name */
9393         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9394         if (fn == NULL)
9395                 goto endofcommand;
9396         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9397                 fn);
9398         COUNT_BYTES(fn_len);
9399
9400         if (check_col(pinfo->cinfo, COL_INFO)) {
9401                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9402         }
9403
9404         END_OF_SMB
9405
9406         /* call AndXCommand (if there are any) */
9407         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9408
9409         return offset;
9410 }
9411
9412
9413 static int
9414 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9415 {
9416         guint8  wc, cmd=0xff;
9417         guint16 andxoffset=0;
9418         guint16 bc;
9419         guint16 fid;
9420
9421         WORD_COUNT;
9422
9423         /* next smb command */
9424         cmd = tvb_get_guint8(tvb, offset);
9425         if(cmd!=0xff){
9426                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9427         } else {
9428                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
9429         }
9430         offset += 1;
9431
9432         /* reserved byte */
9433         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9434         offset += 1;
9435
9436         /* andxoffset */
9437         andxoffset = tvb_get_letohs(tvb, offset);
9438         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9439         offset += 2;
9440
9441         /* oplock level */
9442         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9443         offset += 1;
9444
9445         /* fid */
9446         fid = tvb_get_letohs(tvb, offset);
9447         add_fid(tvb, pinfo, tree, offset, 2, fid);
9448         offset += 2;
9449
9450         /* create action */
9451         /*XXX is this really the same as create disposition in the request? it looks so*/
9452         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9453         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9454         offset += 4;
9455
9456         /* create time */
9457         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9458
9459         /* access time */
9460         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9461
9462         /* last write time */
9463         offset = dissect_smb_64bit_time(tvb, tree, offset,
9464                 hf_smb_last_write_time);
9465
9466         /* last change time */
9467         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9468
9469         /* Extended File Attributes */
9470         offset = dissect_file_ext_attr(tvb, tree, offset);
9471
9472         /* allocation size */
9473         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9474         offset += 8;
9475
9476         /* end of file */
9477         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9478         offset += 8;
9479
9480         /* File Type */
9481         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9482         offset += 2;
9483
9484         /* IPC State */
9485         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9486
9487         /* is directory */
9488         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9489         offset += 1;
9490
9491         BYTE_COUNT;
9492
9493         END_OF_SMB
9494
9495         /* call AndXCommand (if there are any) */
9496         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9497
9498         return offset;
9499 }
9500
9501
9502 static int
9503 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9504 {
9505         guint8 wc;
9506         guint16 bc;
9507
9508         WORD_COUNT;
9509
9510         BYTE_COUNT;
9511
9512         END_OF_SMB
9513
9514         return offset;
9515 }
9516
9517 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9518    BEGIN Transaction/Transaction2 Primary and secondary requests
9519    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9520
9521
9522 const value_string trans2_cmd_vals[] = {
9523         { 0x00,         "OPEN2" },
9524         { 0x01,         "FIND_FIRST2" },
9525         { 0x02,         "FIND_NEXT2" },
9526         { 0x03,         "QUERY_FS_INFORMATION" },
9527         { 0x04,         "SET_FS_QUOTA" },
9528         { 0x05,         "QUERY_PATH_INFORMATION" },
9529         { 0x06,         "SET_PATH_INFORMATION" },
9530         { 0x07,         "QUERY_FILE_INFORMATION" },
9531         { 0x08,         "SET_FILE_INFORMATION" },
9532         { 0x09,         "FSCTL" },
9533         { 0x0A,         "IOCTL2" },
9534         { 0x0B,         "FIND_NOTIFY_FIRST" },
9535         { 0x0C,         "FIND_NOTIFY_NEXT" },
9536         { 0x0D,         "CREATE_DIRECTORY" },
9537         { 0x0E,         "SESSION_SETUP" },
9538         { 0x10,         "GET_DFS_REFERRAL" },
9539         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9540         { 0,    NULL }
9541 };
9542
9543 static const true_false_string tfs_tf_dtid = {
9544         "Also DISCONNECT TID",
9545         "Do NOT disconnect TID"
9546 };
9547 static const true_false_string tfs_tf_owt = {
9548         "One Way Transaction (NO RESPONSE)",
9549         "Two way transaction"
9550 };
9551
9552 static const true_false_string tfs_ff2_backup = {
9553         "Find WITH backup intent",
9554         "No backup intent"
9555 };
9556 static const true_false_string tfs_ff2_continue = {
9557         "CONTINUE search from previous position",
9558         "New search, do NOT continue from previous position"
9559 };
9560 static const true_false_string tfs_ff2_resume = {
9561         "Return RESUME keys",
9562         "Do NOT return resume keys"
9563 };
9564 static const true_false_string tfs_ff2_close_eos = {
9565         "CLOSE search if END OF SEARCH is reached",
9566         "Do NOT close search if end of search reached"
9567 };
9568 static const true_false_string tfs_ff2_close = {
9569         "CLOSE search after this request",
9570         "Do NOT close search after this request"
9571 };
9572
9573 /* used by
9574    TRANS2_FIND_FIRST2
9575 */
9576 static const value_string ff2_il_vals[] = {
9577         { 1,            "Info Standard  (4.3.4.1)"},
9578         { 2,            "Info Query EA Size  (4.3.4.2)"},
9579         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9580         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9581         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9582         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9583         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9584         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9585         {0, NULL}
9586 };
9587
9588 /* values used by :
9589         TRANS2_QUERY_PATH_INFORMATION
9590         TRANS2_QUERY_FILE_INFORMATION
9591 */
9592 static const value_string qpi_loi_vals[] = {
9593         { 1,            "Info Standard  (4.2.16.1)"},
9594         { 2,            "Info Query EA Size  (4.2.16.1)"},
9595         { 3,            "Info Query EAs From List  (4.2.16.2)"},
9596         { 4,            "Info Query All EAs  (4.2.16.2)"},
9597         { 6,            "Info Is Name Valid  (4.2.16.3)"},
9598         { 0x0101,       "Query File Basic Info  (4.2.16.4)"},
9599         { 0x0102,       "Query File Standard Info  (4.2.16.5)"},
9600         { 0x0103,       "Query File EA Info  (4.2.16.6)"},
9601         { 0x0104,       "Query File Name Info  (4.2.16.7)"},
9602         { 0x0107,       "Query File All Info  (4.2.16.8)"},
9603         { 0x0108,       "Query File Alt Name Info  (4.2.16.9)"},
9604         { 0x0109,       "Query File Stream Info  (4.2.16.10)"},
9605         { 0x010b,       "Query File Compression Info  (4.2.16.11)"},
9606         { 0x0200,       "Query File Unix Basic (4.2.16.12)"},
9607         { 0x0201,       "Query File Unix Link (4.2.16.13)"},
9608         { 1004,         "Query File Basic Info  (4.2.16.4)"},
9609         { 1005,         "Query File Standard Info  (4.2.16.5)"},
9610         { 1006,         "Query File Internal Info  (4.2.16.?)"},
9611         { 1007,         "Query File EA Info  (4.2.16.6)"},
9612         { 1009,         "Query File Name Info  (4.2.16.7)"},
9613         { 1010,         "Query File Rename Info  (4.2.16.?)"},
9614         { 1011,         "Query File Link Info  (4.2.16.?)"},
9615         { 1012,         "Query File Names Info  (4.2.16.?)"},
9616         { 1013,         "Query File Disposition Info  (4.2.16.?)"},
9617         { 1014,         "Query File Position Info  (4.2.16.?)"},
9618         { 1015,         "Query File Full EA Info  (4.2.16.?)"},
9619         { 1016,         "Query File Mode Info  (4.2.16.?)"},
9620         { 1017,         "Query File Alignment Info  (4.2.16.?)"},
9621         { 1018,         "Query File All Info  (4.2.16.8)"},
9622         { 1019,         "Query File Allocation Info  (4.2.16.?)"},
9623         { 1020,         "Query File End of File Info  (4.2.16.?)"},
9624         { 1021,         "Query File Alt Name Info  (4.2.16.7)"},
9625         { 1022,         "Query File Stream Info  (4.2.16.10)"},
9626         { 1023,         "Query File Pipe Info  (4.2.16.?)"},
9627         { 1024,         "Query File Pipe Local Info  (4.2.16.?)"},
9628         { 1025,         "Query File Pipe Remote Info  (4.2.16.?)"},
9629         { 1026,         "Query File Mailslot Query Info  (4.2.16.?)"},
9630         { 1027,         "Query File Mailslot Set Info  (4.2.16.?)"},
9631         { 1028,         "Query File Compression Info  (4.2.16.11)"},
9632         { 1029,         "Query File ObjectID Info  (4.2.16.?)"},
9633         { 1030,         "Query File Completion Info  (4.2.16.?)"},
9634         { 1031,         "Query File Move Cluster Info  (4.2.16.?)"},
9635         { 1032,         "Query File Quota Info  (4.2.16.?)"},
9636         { 1033,         "Query File Reparsepoint Info  (4.2.16.?)"},
9637         { 1034,         "Query File Network Open Info  (4.2.16.?)"},
9638         { 1035,         "Query File Attribute Tag Info  (4.2.16.?)"},
9639         { 1036,         "Query File Tracking Info  (4.2.16.?)"},
9640         { 1037,         "Query File Maximum Info  (4.2.16.?)"},
9641         {0, NULL}
9642 };
9643
9644 /* values used by :
9645         TRANS2_SET_PATH_INFORMATION
9646         TRANS2_SET_FILE_INFORMATION
9647         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9648         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9649         well; note that they're different from the QUERY_PATH_INFORMATION
9650         and QUERY_FILE_INFORMATION values!)
9651 */
9652 static const value_string spi_loi_vals[] = {
9653         { 1,            "Info Standard  (4.2.18.1)"},
9654         { 2,            "Info Query EA Size  (4.2.18.1)"},
9655         { 4,            "Info Query All EAs  (4.2.18.2)"},
9656         { 0x0101,       "Set File Basic Info  (4.2.19.1)"},
9657         { 0x0102,       "Set File Disposition Info  (4.2.19.2)"},
9658         { 0x0103,       "Set File Allocation Info  (4.2.19.3)"},
9659         { 0x0104,       "Set File End Of File Info  (4.2.19.4)"},
9660         { 0x0200,       "Set File Unix Basic (4.2.18.3)"},
9661         { 0x0201,       "Set File Unix Link (4.2.18.4)"},
9662         { 0x0202,       "Set File Unix HardLink (4.2.18.5)"},
9663         { 1004,         "Set File Basic Info"},
9664         { 1010,         "Set Rename Information"},
9665         { 1013,         "Set Disposition Information"},
9666         { 1014,         "Set Position Information"},
9667         { 1016,         "Set Mode Information"},
9668         { 1019,         "Set Allocation Information"},
9669         { 1020,         "Set EOF Information"},
9670         { 1023,         "Set File Pipe Information"},
9671         { 1025,         "Set File Pipe Remote Information"},
9672         { 1029,         "Set Copy On Write Information"},
9673         { 1032,         "Set OLE Class ID Information"},
9674         { 1039,         "Set Inherit Context Index Information"},
9675         { 1040,         "Set OLE Information (?)"},
9676         {0, NULL}
9677 };
9678
9679 static const value_string qfsi_vals[] = {
9680         { 1,            "Info Allocation"},
9681         { 2,            "Info Volume"},
9682         { 0x0101,       "Query FS Label Info"},
9683         { 0x0102,       "Query FS Volume Info"},
9684         { 0x0103,       "Query FS Size Info"},
9685         { 0x0104,       "Query FS Device Info"},
9686         { 0x0105,       "Query FS Attribute Info"},
9687         { 0x0200,       "Unix Query FS Info"},
9688         { 0x0301,       "Mac Query FS Info"},
9689         { 1001,         "Query FS Label Info"},
9690         { 1002,         "Query FS Volume Info"},
9691         { 1003,         "Query FS Size Info"},
9692         { 1004,         "Query FS Device Info"},
9693         { 1005,         "Query FS Attribute Info"},
9694         { 1006,         "Query FS Quota Info"},
9695         { 1007,         "Query Full FS Size Info"},
9696         { 1008,         "Object ID Information"},
9697         {0, NULL}
9698 };
9699
9700 static const value_string nt_rename_vals[] = {
9701         { 0x0103,       "Create Hard Link"},
9702         {0, NULL}
9703 };
9704
9705
9706 static const value_string delete_pending_vals[] = {
9707         {0,     "Normal, no pending delete"},
9708         {1,     "This object has DELETE PENDING"},
9709         {0, NULL}
9710 };
9711
9712 static const value_string alignment_vals[] = {
9713         {0,     "Byte alignment"},
9714         {1,     "Word (16bit) alignment"},
9715         {3,     "Long (32bit) alignment"},
9716         {7,     "8 byte boundary alignment"},
9717         {0x0f,  "16 byte boundary alignment"},
9718         {0x1f,  "32 byte boundary alignment"},
9719         {0x3f,  "64 byte boundary alignment"},
9720         {0x7f,  "128 byte boundary alignment"},
9721         {0xff,  "256 byte boundary alignment"},
9722         {0x1ff, "512 byte boundary alignment"},
9723         {0, NULL}
9724 };
9725
9726 static const true_false_string tfs_marked_for_deletion = {
9727         "File is MARKED FOR DELETION",
9728         "File is NOT marked for deletion"
9729 };
9730
9731 static const true_false_string tfs_get_dfs_server_hold_storage = {
9732         "Referral SERVER HOLDS STORAGE for the file",
9733         "Referral server does NOT hold storage for the file"
9734 };
9735 static const true_false_string tfs_get_dfs_fielding = {
9736         "The server in referral is FIELDING CAPABLE",
9737         "The server in referrals is NOT fielding capable"
9738 };
9739
9740 static const true_false_string tfs_dfs_referral_flags_strip = {
9741         "STRIP off pathconsumed characters before submitting",
9742         "Do NOT strip off any characters"
9743 };
9744
9745 static const value_string dfs_referral_server_type_vals[] = {
9746         {0,     "Don't know"},
9747         {1,     "SMB Server"},
9748         {2,     "Netware Server"},
9749         {3,     "Domain Server"},
9750         {0, NULL}
9751 };
9752
9753
9754 static const true_false_string tfs_device_char_removable = {
9755         "This is a REMOVABLE device",
9756         "This is NOT a removable device"
9757 };
9758 static const true_false_string tfs_device_char_read_only = {
9759         "This is a READ-ONLY device",
9760         "This is NOT a read-only device"
9761 };
9762 static const true_false_string tfs_device_char_floppy = {
9763         "This is a FLOPPY DISK device",
9764         "This is NOT a floppy disk device"
9765 };
9766 static const true_false_string tfs_device_char_write_once = {
9767         "This is a WRITE-ONCE device",
9768         "This is NOT a write-once device"
9769 };
9770 static const true_false_string tfs_device_char_remote = {
9771         "This is a REMOTE device",
9772         "This is NOT a remote device"
9773 };
9774 static const true_false_string tfs_device_char_mounted = {
9775         "This device is MOUNTED",
9776         "This device is NOT mounted"
9777 };
9778 static const true_false_string tfs_device_char_virtual = {
9779         "This is a VIRTUAL device",
9780         "This is NOT a virtual device"
9781 };
9782
9783
9784 static const true_false_string tfs_fs_attr_css = {
9785         "This FS supports CASE SENSITIVE SEARCHes",
9786         "This FS does NOT support case sensitive searches"
9787 };
9788 static const true_false_string tfs_fs_attr_cpn = {
9789         "This FS supports CASE PRESERVED NAMES",
9790         "This FS does NOT support case preserved names"
9791 };
9792 static const true_false_string tfs_fs_attr_pacls = {
9793         "This FS supports PERSISTENT ACLs",
9794         "This FS does NOT support persistent acls"
9795 };
9796 static const true_false_string tfs_fs_attr_fc = {
9797         "This FS supports COMPRESSED FILES",
9798         "This FS does NOT support compressed files"
9799 };
9800 static const true_false_string tfs_fs_attr_vq = {
9801         "This FS supports VOLUME QUOTAS",
9802         "This FS does NOT support volume quotas"
9803 };
9804 static const true_false_string tfs_fs_attr_dim = {
9805         "This FS is on a MOUNTED DEVICE",
9806         "This FS is NOT on a mounted device"
9807 };
9808 static const true_false_string tfs_fs_attr_vic = {
9809         "This FS is on a COMPRESSED VOLUME",
9810         "This FS is NOT on a compressed volume"
9811 };
9812
9813 #define FF2_RESUME      0x0004
9814
9815 static int
9816 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9817 {
9818         guint16 mask;
9819         proto_item *item = NULL;
9820         proto_tree *tree = NULL;
9821         smb_info_t *si;
9822         smb_transact2_info_t *t2i;
9823
9824         mask = tvb_get_letohs(tvb, offset);
9825
9826         si = (smb_info_t *)pinfo->private_data;
9827         if (si->sip != NULL) {
9828                 t2i = si->sip->extra_info;
9829                 if (t2i != NULL) {
9830                         if (!pinfo->fd->flags.visited)
9831                                 t2i->resume_keys = (mask & FF2_RESUME);
9832                 }
9833         }
9834
9835         if(parent_tree){
9836                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9837                         "Flags: 0x%04x", mask);
9838                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9839         }
9840
9841         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9842                 tvb, offset, 2, mask);
9843         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9844                 tvb, offset, 2, mask);
9845         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9846                 tvb, offset, 2, mask);
9847         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9848                 tvb, offset, 2, mask);
9849         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9850                 tvb, offset, 2, mask);
9851
9852         offset += 2;
9853
9854         return offset;
9855 }
9856
9857 #if 0
9858 static int
9859 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9860 {
9861         guint16 mask;
9862         proto_item *item = NULL;
9863         proto_tree *tree = NULL;
9864
9865         mask = tvb_get_letohs(tvb, offset);
9866
9867         if(parent_tree){
9868                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9869                         "IO Flag: 0x%04x", mask);
9870                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9871         }
9872
9873         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9874                 tvb, offset, 2, mask);
9875         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9876                 tvb, offset, 2, mask);
9877
9878         offset += 2;
9879
9880         return offset;
9881 }
9882 #endif
9883
9884 static int
9885 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9886     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9887 {
9888         proto_item *item = NULL;
9889         proto_tree *tree = NULL;
9890         smb_info_t *si;
9891         smb_transact2_info_t *t2i;
9892         int fn_len;
9893         const char *fn;
9894         int old_offset = offset;
9895
9896         si = (smb_info_t *)pinfo->private_data;
9897         if (si->sip != NULL)
9898                 t2i = si->sip->extra_info;
9899         else
9900                 t2i = NULL;
9901
9902         if(parent_tree){
9903                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9904                                 "%s Parameters",
9905                                 val_to_str(subcmd, trans2_cmd_vals,
9906                                            "Unknown (0x%02x)"));
9907                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9908         }
9909
9910         switch(subcmd){
9911         case 0x00:      /*TRANS2_OPEN2*/
9912                 /* open flags */
9913                 CHECK_BYTE_COUNT_TRANS(2);
9914                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9915                 bc -= 2;
9916
9917                 /* desired access */
9918                 CHECK_BYTE_COUNT_TRANS(2);
9919                 offset = dissect_access(tvb, tree, offset, "Desired");
9920                 bc -= 2;
9921
9922                 /* Search Attributes */
9923                 CHECK_BYTE_COUNT_TRANS(2);
9924                 offset = dissect_search_attributes(tvb, tree, offset);
9925                 bc -= 2;
9926
9927                 /* File Attributes */
9928                 CHECK_BYTE_COUNT_TRANS(2);
9929                 offset = dissect_file_attributes(tvb, tree, offset, 2);
9930                 bc -= 2;
9931
9932                 /* create time */
9933                 CHECK_BYTE_COUNT_TRANS(4);
9934                 offset = dissect_smb_datetime(tvb, tree, offset,
9935                         hf_smb_create_time,
9936                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9937                         TRUE);
9938                 bc -= 4;
9939
9940                 /* open function */
9941                 CHECK_BYTE_COUNT_TRANS(2);
9942                 offset = dissect_open_function(tvb, tree, offset);
9943                 bc -= 2;
9944
9945                 /* allocation size */
9946                 CHECK_BYTE_COUNT_TRANS(4);
9947                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9948                 COUNT_BYTES_TRANS(4);
9949
9950                 /* 10 reserved bytes */
9951                 CHECK_BYTE_COUNT_TRANS(10);
9952                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9953                 COUNT_BYTES_TRANS(10);
9954
9955                 /* file name */
9956                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9957                 CHECK_STRING_TRANS(fn);
9958                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9959                         fn);
9960                 COUNT_BYTES_TRANS(fn_len);
9961
9962                 if (check_col(pinfo->cinfo, COL_INFO)) {
9963                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9964                         fn);
9965                 }
9966                 break;
9967         case 0x01:      /*TRANS2_FIND_FIRST2*/
9968                 /* Search Attributes */
9969                 CHECK_BYTE_COUNT_TRANS(2);
9970                 offset = dissect_search_attributes(tvb, tree, offset);
9971                 bc -= 2;
9972
9973                 /* search count */
9974                 CHECK_BYTE_COUNT_TRANS(2);
9975                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9976                 COUNT_BYTES_TRANS(2);
9977
9978                 /* Find First2 flags */
9979                 CHECK_BYTE_COUNT_TRANS(2);
9980                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9981                 bc -= 2;
9982
9983                 /* Find First2 information level */
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_ff2_information_level, tvb, offset, 2, si->info_level);
9989                 COUNT_BYTES_TRANS(2);
9990
9991                 /* storage type */
9992                 CHECK_BYTE_COUNT_TRANS(4);
9993                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9994                 COUNT_BYTES_TRANS(4);
9995
9996                 /* search pattern */
9997                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9998                 CHECK_STRING_TRANS(fn);
9999                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10000                         fn);
10001                 COUNT_BYTES_TRANS(fn_len);
10002
10003                 if (check_col(pinfo->cinfo, COL_INFO)) {
10004                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10005                         fn);
10006                 }
10007
10008                 break;
10009         case 0x02:      /*TRANS2_FIND_NEXT2*/
10010                 /* sid */
10011                 CHECK_BYTE_COUNT_TRANS(2);
10012                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10013                 COUNT_BYTES_TRANS(2);
10014
10015                 /* search count */
10016                 CHECK_BYTE_COUNT_TRANS(2);
10017                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10018                 COUNT_BYTES_TRANS(2);
10019
10020                 /* Find First2 information level */
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_ff2_information_level, tvb, offset, 2, si->info_level);
10026                 COUNT_BYTES_TRANS(2);
10027
10028                 /* resume key */
10029                 CHECK_BYTE_COUNT_TRANS(4);
10030                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10031                 COUNT_BYTES_TRANS(4);
10032
10033                 /* Find First2 flags */
10034                 CHECK_BYTE_COUNT_TRANS(2);
10035                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10036                 bc -= 2;
10037
10038                 /* file name */
10039                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10040                 CHECK_STRING_TRANS(fn);
10041                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10042                         fn);
10043                 COUNT_BYTES_TRANS(fn_len);
10044
10045                 if (check_col(pinfo->cinfo, COL_INFO)) {
10046                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10047                         fn);
10048                 }
10049
10050                 break;
10051         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10052                 /* level of interest */
10053                 CHECK_BYTE_COUNT_TRANS(2);
10054                 si->info_level = tvb_get_letohs(tvb, offset);
10055                 if (!pinfo->fd->flags.visited)
10056                         t2i->info_level = si->info_level;
10057                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10058                 COUNT_BYTES_TRANS(2);
10059
10060                 if (check_col(pinfo->cinfo, COL_INFO))
10061                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10062                                         val_to_str(si->info_level, qfsi_vals, 
10063                                                    "Unknown (0x%02x)"));
10064
10065                 break;
10066         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10067                 /* level of interest */
10068                 CHECK_BYTE_COUNT_TRANS(2);
10069                 si->info_level = tvb_get_letohs(tvb, offset);
10070                 if (!pinfo->fd->flags.visited)
10071                         t2i->info_level = si->info_level;
10072                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10073                 COUNT_BYTES_TRANS(2);
10074
10075                 /* 4 reserved bytes */
10076                 CHECK_BYTE_COUNT_TRANS(4);
10077                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10078                 COUNT_BYTES_TRANS(4);
10079
10080                 /* file name */
10081                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10082                 CHECK_STRING_TRANS(fn);
10083                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10084                         fn);
10085                 COUNT_BYTES_TRANS(fn_len);
10086
10087                 if (check_col(pinfo->cinfo, COL_INFO)) {
10088                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10089                         fn);
10090                 }
10091
10092                 break;
10093         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10094                 /* level of interest */
10095                 CHECK_BYTE_COUNT_TRANS(2);
10096                 si->info_level = tvb_get_letohs(tvb, offset);
10097                 if (!pinfo->fd->flags.visited)
10098                         t2i->info_level = si->info_level;
10099                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10100                 COUNT_BYTES_TRANS(2);
10101
10102                 /* 4 reserved bytes */
10103                 CHECK_BYTE_COUNT_TRANS(4);
10104                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10105                 COUNT_BYTES_TRANS(4);
10106
10107                 /* file name */
10108                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10109                 CHECK_STRING_TRANS(fn);
10110                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10111                         fn);
10112                 COUNT_BYTES_TRANS(fn_len);
10113
10114                 if (check_col(pinfo->cinfo, COL_INFO)) {
10115                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10116                         fn);
10117                 }
10118
10119                 break;
10120         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10121                 guint16 fid;
10122
10123                 /* fid */
10124                 CHECK_BYTE_COUNT_TRANS(2);
10125                 fid = tvb_get_letohs(tvb, offset);
10126                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10127                 COUNT_BYTES_TRANS(2);
10128
10129                 /* level of interest */
10130                 CHECK_BYTE_COUNT_TRANS(2);
10131                 si->info_level = tvb_get_letohs(tvb, offset);
10132                 if (!pinfo->fd->flags.visited)
10133                         t2i->info_level = si->info_level;
10134                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10135                 COUNT_BYTES_TRANS(2);
10136
10137                 break;
10138         }
10139         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10140                 guint16 fid;
10141
10142                 /* fid */
10143                 CHECK_BYTE_COUNT_TRANS(2);
10144                 fid = tvb_get_letohs(tvb, offset);
10145                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10146                 COUNT_BYTES_TRANS(2);
10147
10148                 /* level of interest */
10149                 CHECK_BYTE_COUNT_TRANS(2);
10150                 si->info_level = tvb_get_letohs(tvb, offset);
10151                 if (!pinfo->fd->flags.visited)
10152                         t2i->info_level = si->info_level;
10153                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10154                 COUNT_BYTES_TRANS(2);
10155
10156 #if 0
10157                 /*
10158                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10159                  * Extensions Version 3.0, Document Version 1.11,
10160                  * July 19, 1990" says this is I/O flags, but it's
10161                  * reserved in the SNIA spec, and some clients appear
10162                  * to leave junk in it.
10163                  *
10164                  * Is this some field used only if a particular
10165                  * dialect was negotiated, so that clients can feel
10166                  * safe not setting it if they haven't negotiated that
10167                  * dialect?  Or do the (non-OS/2) clients simply not care
10168                  * about that particular OS/2-oriented dialect?
10169                  */
10170
10171                 /* IO Flag */
10172                 CHECK_BYTE_COUNT_TRANS(2);
10173                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10174                 bc -= 2;
10175 #else
10176                 /* 2 reserved bytes */
10177                 CHECK_BYTE_COUNT_TRANS(2);
10178                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10179                 COUNT_BYTES_TRANS(2);
10180 #endif
10181
10182                 break;
10183         }
10184         case 0x09:      /*TRANS2_FSCTL*/
10185                 /* this call has no parameter block in the request */
10186
10187                 /*
10188                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10189                  * Extensions Version 3.0, Document Version 1.11,
10190                  * July 19, 1990" says this this contains a
10191                  * "File system specific parameter block".  (That means
10192                  * we may not be able to dissect it in any case.)
10193                  */
10194                 break;
10195         case 0x0a:      /*TRANS2_IOCTL2*/
10196                 /* this call has no parameter block in the request */
10197
10198                 /*
10199                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10200                  * Extensions Version 3.0, Document Version 1.11,
10201                  * July 19, 1990" says this this contains a
10202                  * "Device/function specific parameter block".  (That
10203                  * means we may not be able to dissect it in any case.)
10204                  */
10205                 break;
10206         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10207                 /* Search Attributes */
10208                 CHECK_BYTE_COUNT_TRANS(2);
10209                 offset = dissect_search_attributes(tvb, tree, offset);
10210                 bc -= 2;
10211
10212                 /* Number of changes to wait for */
10213                 CHECK_BYTE_COUNT_TRANS(2);
10214                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10215                 COUNT_BYTES_TRANS(2);
10216
10217                 /* Find Notify information level */
10218                 CHECK_BYTE_COUNT_TRANS(2);
10219                 si->info_level = tvb_get_letohs(tvb, offset);
10220                 if (!pinfo->fd->flags.visited)
10221                         t2i->info_level = si->info_level;
10222                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10223                 COUNT_BYTES_TRANS(2);
10224
10225                 /* 4 reserved bytes */
10226                 CHECK_BYTE_COUNT_TRANS(4);
10227                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10228                 COUNT_BYTES_TRANS(4);
10229
10230                 /* file name */
10231                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10232                 CHECK_STRING_TRANS(fn);
10233                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10234                         fn);
10235                 COUNT_BYTES_TRANS(fn_len);
10236
10237                 if (check_col(pinfo->cinfo, COL_INFO)) {
10238                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10239                         fn);
10240                 }
10241
10242                 break;
10243         }
10244         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10245                 /* Monitor handle */
10246                 CHECK_BYTE_COUNT_TRANS(2);
10247                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10248                 COUNT_BYTES_TRANS(2);
10249
10250                 /* Number of changes to wait for */
10251                 CHECK_BYTE_COUNT_TRANS(2);
10252                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10253                 COUNT_BYTES_TRANS(2);
10254
10255                 break;
10256         }
10257         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10258                 /* 4 reserved bytes */
10259                 CHECK_BYTE_COUNT_TRANS(4);
10260                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10261                 COUNT_BYTES_TRANS(4);
10262
10263                 /* dir name */
10264                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10265                         FALSE, FALSE, &bc);
10266                 CHECK_STRING_TRANS(fn);
10267                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10268                         fn);
10269                 COUNT_BYTES_TRANS(fn_len);
10270
10271                 if (check_col(pinfo->cinfo, COL_INFO)) {
10272                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10273                         fn);
10274                 }
10275                 break;
10276         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10277                 /* XXX unknown structure*/
10278                 break;
10279         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10280                 /* referral level */
10281                 CHECK_BYTE_COUNT_TRANS(2);
10282                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10283                 COUNT_BYTES_TRANS(2);
10284
10285                 /* file name */
10286                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10287                 CHECK_STRING_TRANS(fn);
10288                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10289                         fn);
10290                 COUNT_BYTES_TRANS(fn_len);
10291
10292                 if (check_col(pinfo->cinfo, COL_INFO)) {
10293                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10294                         fn);
10295                 }
10296
10297                 break;
10298         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10299                 /* file name */
10300                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10301                 CHECK_STRING_TRANS(fn);
10302                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10303                         fn);
10304                 COUNT_BYTES_TRANS(fn_len);
10305
10306                 if (check_col(pinfo->cinfo, COL_INFO)) {
10307                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10308                         fn);
10309                 }
10310
10311                 break;
10312         }
10313
10314         /* ooops there were data we didnt know how to process */
10315         if((offset-old_offset) < bc){
10316                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
10317                     bc - (offset-old_offset), TRUE);
10318                 offset += bc - (offset-old_offset);
10319         }
10320
10321         return offset;
10322 }
10323
10324 /*
10325  * XXX - just use "dissect_connect_flags()" here?
10326  */
10327 static guint16
10328 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10329 {
10330         guint16 mask;
10331         proto_item *item = NULL;
10332         proto_tree *tree = NULL;
10333
10334         mask = tvb_get_letohs(tvb, offset);
10335
10336         if(parent_tree){
10337                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10338                         "Flags: 0x%04x", mask);
10339                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10340         }
10341
10342         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10343                 tvb, offset, 2, mask);
10344         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10345                 tvb, offset, 2, mask);
10346
10347         return mask;
10348 }
10349
10350
10351 static int
10352 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10353 {
10354         guint16 mask;
10355         proto_item *item = NULL;
10356         proto_tree *tree = NULL;
10357
10358         mask = tvb_get_letohs(tvb, offset);
10359
10360         if(parent_tree){
10361                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10362                         "Flags: 0x%04x", mask);
10363                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10364         }
10365
10366         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10367                 tvb, offset, 2, mask);
10368         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10369                 tvb, offset, 2, mask);
10370
10371         offset += 2;
10372         return offset;
10373 }
10374
10375 static int
10376 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10377 {
10378         guint16 mask;
10379         proto_item *item = NULL;
10380         proto_tree *tree = NULL;
10381
10382         mask = tvb_get_letohs(tvb, offset);
10383
10384         if(parent_tree){
10385                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10386                         "Flags: 0x%04x", mask);
10387                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10388         }
10389
10390         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10391                 tvb, offset, 2, mask);
10392
10393         offset += 2;
10394
10395         return offset;
10396 }
10397
10398
10399 /* dfs inconsistency data  (4.4.2)
10400 */
10401 static int
10402 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10403     proto_tree *tree, int offset, guint16 *bcp)
10404 {
10405         smb_info_t *si = pinfo->private_data;
10406         int fn_len;
10407         const char *fn;
10408
10409         /*XXX shouldn this data hold version and size? unclear from doc*/
10410         /* referral version */
10411         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10412         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10413         COUNT_BYTES_TRANS_SUBR(2);
10414
10415         /* referral size */
10416         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10417         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10418         COUNT_BYTES_TRANS_SUBR(2);
10419
10420         /* referral server type */
10421         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10422         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10423         COUNT_BYTES_TRANS_SUBR(2);
10424
10425         /* referral flags */
10426         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10427         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10428         *bcp -= 2;
10429
10430         /* node name */
10431         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10432         CHECK_STRING_TRANS_SUBR(fn);
10433         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10434                 fn);
10435         COUNT_BYTES_TRANS_SUBR(fn_len);
10436
10437         return offset;
10438 }
10439
10440 /* get dfs referral data  (4.4.1)
10441 */
10442 static int
10443 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10444     proto_tree *tree, int offset, guint16 *bcp)
10445 {
10446         smb_info_t *si = pinfo->private_data;
10447         guint16 numref;
10448         guint16 refsize;
10449         guint16 pathoffset;
10450         guint16 altpathoffset;
10451         guint16 nodeoffset;
10452         int fn_len;
10453         int stroffset;
10454         int offsetoffset;
10455         guint16 save_bc;
10456         const char *fn;
10457         int unklen;
10458         int ucstring_end;
10459         int ucstring_len;
10460
10461         /* path consumed */
10462         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10463         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10464         COUNT_BYTES_TRANS_SUBR(2);
10465
10466         /* num referrals */
10467         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10468         numref = tvb_get_letohs(tvb, offset);
10469         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10470         COUNT_BYTES_TRANS_SUBR(2);
10471
10472         /* get dfs flags */
10473         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10474         offset = dissect_get_dfs_flags(tvb, tree, offset);
10475         *bcp -= 2;
10476
10477         /* XXX - in at least one capture there appears to be 2 bytes
10478            of stuff after the Dfs flags, perhaps so that the header
10479            in front of the referral list is a multiple of 4 bytes long. */
10480         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10481         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10482         COUNT_BYTES_TRANS_SUBR(2);
10483
10484         /* if there are any referrals */
10485         if(numref){
10486                 proto_item *ref_item = NULL;
10487                 proto_tree *ref_tree = NULL;
10488                 int old_offset=offset;
10489
10490                 if(tree){
10491                         ref_item = proto_tree_add_text(tree,
10492                                 tvb, offset, *bcp, "Referrals");
10493                         ref_tree = proto_item_add_subtree(ref_item,
10494                                 ett_smb_dfs_referrals);
10495                 }
10496                 ucstring_end = -1;
10497
10498                 while(numref--){
10499                         proto_item *ri = NULL;
10500                         proto_tree *rt = NULL;
10501                         int old_offset=offset;
10502                         guint16 version;
10503
10504                         if(tree){
10505                                 ri = proto_tree_add_text(ref_tree,
10506                                         tvb, offset, *bcp, "Referral");
10507                                 rt = proto_item_add_subtree(ri,
10508                                         ett_smb_dfs_referral);
10509                         }
10510
10511                         /* referral version */
10512                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10513                         version = tvb_get_letohs(tvb, offset);
10514                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10515                                 tvb, offset, 2, version);
10516                         COUNT_BYTES_TRANS_SUBR(2);
10517
10518                         /* referral size */
10519                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10520                         refsize = tvb_get_letohs(tvb, offset);
10521                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10522                         COUNT_BYTES_TRANS_SUBR(2);
10523
10524                         /* referral server type */
10525                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10526                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10527                         COUNT_BYTES_TRANS_SUBR(2);
10528
10529                         /* referral flags */
10530                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10531                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10532                         *bcp -= 2;
10533
10534                         switch(version){
10535
10536                         case 1:
10537                                 /* node name */
10538                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10539                                 CHECK_STRING_TRANS_SUBR(fn);
10540                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10541                                         fn);
10542                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10543                                 break;
10544
10545                         case 2:
10546                         case 3: /* XXX - like version 2, but not identical;
10547                                    seen in a capture, but the format isn't
10548                                    documented */
10549                                 /* proximity */
10550                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10551                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10552                                 COUNT_BYTES_TRANS_SUBR(2);
10553
10554                                 /* ttl */
10555                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10556                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10557                                 COUNT_BYTES_TRANS_SUBR(2);
10558
10559                                 /* path offset */
10560                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10561                                 pathoffset = tvb_get_letohs(tvb, offset);
10562                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10563                                 COUNT_BYTES_TRANS_SUBR(2);
10564
10565                                 /* alt path offset */
10566                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10567                                 altpathoffset = tvb_get_letohs(tvb, offset);
10568                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10569                                 COUNT_BYTES_TRANS_SUBR(2);
10570
10571                                 /* node offset */
10572                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10573                                 nodeoffset = tvb_get_letohs(tvb, offset);
10574                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10575                                 COUNT_BYTES_TRANS_SUBR(2);
10576
10577                                 /* path */
10578                                 if (pathoffset != 0) {
10579                                         stroffset = old_offset + pathoffset;
10580                                         offsetoffset = stroffset - offset;
10581                                         if (offsetoffset > 0 &&
10582                                             *bcp > offsetoffset) {
10583                                                 save_bc = *bcp;
10584                                                 *bcp -= offsetoffset;
10585                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10586                                                 CHECK_STRING_TRANS_SUBR(fn);
10587                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10588                                                         fn);
10589                                                 stroffset += fn_len;
10590                                                 if (ucstring_end < stroffset)
10591                                                         ucstring_end = stroffset;
10592                                                 *bcp = save_bc;
10593                                         }
10594                                 }
10595
10596                                 /* alt path */
10597                                 if (altpathoffset != 0) {
10598                                         stroffset = old_offset + altpathoffset;
10599                                         offsetoffset = stroffset - offset;
10600                                         if (offsetoffset > 0 &&
10601                                             *bcp > offsetoffset) {
10602                                                 save_bc = *bcp;
10603                                                 *bcp -= offsetoffset;
10604                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10605                                                 CHECK_STRING_TRANS_SUBR(fn);
10606                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10607                                                         fn);
10608                                                 stroffset += fn_len;
10609                                                 if (ucstring_end < stroffset)
10610                                                         ucstring_end = stroffset;
10611                                                 *bcp = save_bc;
10612                                         }
10613                                 }
10614
10615                                 /* node */
10616                                 if (nodeoffset != 0) {
10617                                         stroffset = old_offset + nodeoffset;
10618                                         offsetoffset = stroffset - offset;
10619                                         if (offsetoffset > 0 &&
10620                                             *bcp > offsetoffset) {
10621                                                 save_bc = *bcp;
10622                                                 *bcp -= offsetoffset;
10623                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10624                                                 CHECK_STRING_TRANS_SUBR(fn);
10625                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10626                                                         fn);
10627                                                 stroffset += fn_len;
10628                                                 if (ucstring_end < stroffset)
10629                                                         ucstring_end = stroffset;
10630                                                 *bcp = save_bc;
10631                                         }
10632                                 }
10633                                 break;
10634                         }
10635
10636                         /*
10637                          * Show anything beyond the length of the referral
10638                          * as unknown data.
10639                          */
10640                         unklen = (old_offset + refsize) - offset;
10641                         if (unklen < 0) {
10642                                 /*
10643                                  * XXX - the length is bogus.
10644                                  */
10645                                 unklen = 0;
10646                         }
10647                         if (unklen != 0) {
10648                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10649                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10650                                     offset, unklen, TRUE);
10651                                 COUNT_BYTES_TRANS_SUBR(unklen);
10652                         }
10653
10654                         proto_item_set_len(ri, offset-old_offset);
10655                 }
10656
10657                 /*
10658                  * Treat the offset past the end of the last Unicode
10659                  * string after the referrals (if any) as the last
10660                  * offset.
10661                  */
10662                 if (ucstring_end > offset) {
10663                         ucstring_len = ucstring_end - offset;
10664                         if (*bcp < ucstring_len)
10665                                 ucstring_len = *bcp;
10666                         offset += ucstring_len;
10667                         *bcp -= ucstring_len;
10668                 }
10669                 proto_item_set_len(ref_item, offset-old_offset);
10670         }
10671
10672         return offset;
10673 }
10674
10675
10676 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10677    as described in 4.2.16.1
10678 */
10679 static int
10680 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10681     int offset, guint16 *bcp, gboolean *trunc)
10682 {
10683         /* create time */
10684         CHECK_BYTE_COUNT_SUBR(4);
10685         offset = dissect_smb_datetime(tvb, tree, offset,
10686                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10687                 FALSE);
10688         *bcp -= 4;
10689
10690         /* access time */
10691         CHECK_BYTE_COUNT_SUBR(4);
10692         offset = dissect_smb_datetime(tvb, tree, offset,
10693                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10694                 FALSE);
10695         *bcp -= 4;
10696
10697         /* last write time */
10698         CHECK_BYTE_COUNT_SUBR(4);
10699         offset = dissect_smb_datetime(tvb, tree, offset,
10700                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10701                 FALSE);
10702         *bcp -= 4;
10703
10704         /* data size */
10705         CHECK_BYTE_COUNT_SUBR(4);
10706         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10707         COUNT_BYTES_SUBR(4);
10708
10709         /* allocation size */
10710         CHECK_BYTE_COUNT_SUBR(4);
10711         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10712         COUNT_BYTES_SUBR(4);
10713
10714         /* File Attributes */
10715         CHECK_BYTE_COUNT_SUBR(2);
10716         offset = dissect_file_attributes(tvb, tree, offset, 2);
10717         *bcp -= 2;
10718
10719         /* ea length */
10720         CHECK_BYTE_COUNT_SUBR(4);
10721         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10722         COUNT_BYTES_SUBR(4);
10723
10724         *trunc = FALSE;
10725         return offset;
10726 }
10727
10728 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10729    as described in 4.2.16.2
10730 */
10731 static int
10732 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10733     int offset, guint16 *bcp, gboolean *trunc)
10734 {
10735         guint8 name_len;
10736         guint16 data_len;
10737         /* EA size */
10738
10739         CHECK_BYTE_COUNT_SUBR(4);
10740         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10741         COUNT_BYTES_SUBR(4);
10742
10743         while (*bcp > 0) {
10744                 proto_item *item;
10745                 proto_tree *subtree;
10746                 int start_offset = offset;
10747                 guint8 *name;
10748
10749                 item = proto_tree_add_text(
10750                         tree, tvb, offset, 0, "Extended Attribute");
10751                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10752
10753                 /* EA flags */
10754                 
10755                 CHECK_BYTE_COUNT_SUBR(1);
10756                 proto_tree_add_item(
10757                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10758                 COUNT_BYTES_SUBR(1);
10759
10760                 /* EA name length */
10761                 
10762                 name_len = tvb_get_guint8(tvb, offset);
10763
10764                 CHECK_BYTE_COUNT_SUBR(1);
10765                 proto_tree_add_item(
10766                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10767                 COUNT_BYTES_SUBR(1);
10768
10769                 /* EA data length */
10770
10771                 data_len = tvb_get_letohs(tvb, offset);
10772                 
10773                 CHECK_BYTE_COUNT_SUBR(2);
10774                 proto_tree_add_item(
10775                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10776                 COUNT_BYTES_SUBR(2);
10777
10778                 /* EA name */
10779
10780                 name = tvb_get_string(tvb, offset, name_len);
10781                 proto_item_append_text(item, ": %s", name);
10782                 g_free(name);
10783
10784                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10785                 proto_tree_add_item(
10786                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10787                         TRUE);
10788                 COUNT_BYTES_SUBR(name_len + 1);
10789
10790                 /* EA data */
10791                 
10792                 CHECK_BYTE_COUNT_SUBR(data_len);
10793                 proto_tree_add_item(
10794                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10795                 COUNT_BYTES_SUBR(data_len);
10796
10797                 proto_item_set_len(item, offset - start_offset);
10798         }
10799
10800         *trunc = FALSE;
10801         return offset;
10802 }
10803
10804 /* this dissects the SMB_INFO_IS_NAME_VALID
10805    as described in 4.2.16.3
10806 */
10807 static int
10808 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10809     int offset, guint16 *bcp, gboolean *trunc)
10810 {
10811         smb_info_t *si = pinfo->private_data;
10812         int fn_len;
10813         const char *fn;
10814
10815         /* file name */
10816         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10817         CHECK_STRING_SUBR(fn);
10818         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10819                 fn);
10820         COUNT_BYTES_SUBR(fn_len);
10821
10822         *trunc = FALSE;
10823         return offset;
10824 }
10825
10826 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10827    as described in 4.2.16.4
10828 */
10829 static int
10830 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10831     int offset, guint16 *bcp, gboolean *trunc)
10832 {
10833         /* create time */
10834         CHECK_BYTE_COUNT_SUBR(8);
10835         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10836         *bcp -= 8;
10837
10838         /* access time */
10839         CHECK_BYTE_COUNT_SUBR(8);
10840         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10841         *bcp -= 8;
10842
10843         /* last write time */
10844         CHECK_BYTE_COUNT_SUBR(8);
10845         offset = dissect_smb_64bit_time(tvb, tree, offset,
10846                 hf_smb_last_write_time);
10847         *bcp -= 8;
10848
10849         /* last change time */
10850         CHECK_BYTE_COUNT_SUBR(8);
10851         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10852         *bcp -= 8;
10853
10854         /* File Attributes */
10855         CHECK_BYTE_COUNT_SUBR(4);
10856         offset = dissect_file_attributes(tvb, tree, offset, 4);
10857         *bcp -= 4;
10858
10859         *trunc = FALSE;
10860         return offset;
10861 }
10862
10863 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10864    as described in 4.2.16.5
10865 */
10866 static int
10867 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10868     int offset, guint16 *bcp, gboolean *trunc)
10869 {
10870         /* allocation size */
10871         CHECK_BYTE_COUNT_SUBR(8);
10872         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10873         COUNT_BYTES_SUBR(8);
10874
10875         /* end of file */
10876         CHECK_BYTE_COUNT_SUBR(8);
10877         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10878         COUNT_BYTES_SUBR(8);
10879
10880         /* number of links */
10881         CHECK_BYTE_COUNT_SUBR(4);
10882         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10883         COUNT_BYTES_SUBR(4);
10884
10885         /* delete pending */
10886         CHECK_BYTE_COUNT_SUBR(1);
10887         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
10888         COUNT_BYTES_SUBR(1);
10889
10890         /* is directory */
10891         CHECK_BYTE_COUNT_SUBR(1);
10892         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10893         COUNT_BYTES_SUBR(1);
10894
10895         *trunc = FALSE;
10896         return offset;
10897 }
10898
10899 /* this dissects the SMB_QUERY_FILE_EA_INFO
10900    as described in 4.2.16.6
10901 */
10902 static int
10903 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10904     int offset, guint16 *bcp, gboolean *trunc)
10905 {
10906         /* ea length */
10907         CHECK_BYTE_COUNT_SUBR(4);
10908         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10909         COUNT_BYTES_SUBR(4);
10910
10911         *trunc = FALSE;
10912         return offset;
10913 }
10914
10915 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10916    as described in 4.2.16.7
10917    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10918    as described in 4.2.16.9
10919 */
10920 static int
10921 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10922     int offset, guint16 *bcp, gboolean *trunc)
10923 {
10924         smb_info_t *si = pinfo->private_data;
10925         int fn_len;
10926         const char *fn;
10927
10928         /* file name len */
10929         CHECK_BYTE_COUNT_SUBR(4);
10930         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10931         COUNT_BYTES_SUBR(4);
10932
10933         /* file name */
10934         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10935         CHECK_STRING_SUBR(fn);
10936         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10937                 fn);
10938         COUNT_BYTES_SUBR(fn_len);
10939
10940         *trunc = FALSE;
10941         return offset;
10942 }
10943
10944 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10945    as described in 4.2.16.8
10946 */
10947 static int
10948 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10949     int offset, guint16 *bcp, gboolean *trunc)
10950 {
10951
10952         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
10953         if (*trunc) {
10954                 return offset;
10955         }
10956         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
10957         if (*trunc) {
10958                 return offset;
10959         }
10960
10961         /* index number */
10962         CHECK_BYTE_COUNT_SUBR(8);
10963         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10964         COUNT_BYTES_SUBR(8);
10965
10966         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10967         if (*trunc)
10968                 return offset;
10969
10970         /* access flags */
10971         CHECK_BYTE_COUNT_SUBR(4);
10972         offset = dissect_smb_access_mask(tvb, tree, offset);
10973         COUNT_BYTES_SUBR(4);
10974
10975         /* index number */
10976         CHECK_BYTE_COUNT_SUBR(8);
10977         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10978         COUNT_BYTES_SUBR(8);
10979
10980         /* current offset */
10981         CHECK_BYTE_COUNT_SUBR(8);
10982         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10983         COUNT_BYTES_SUBR(8);
10984
10985         /* mode */
10986         CHECK_BYTE_COUNT_SUBR(4);
10987         offset = dissect_nt_create_options(tvb, tree, offset);
10988         *bcp -= 4;
10989
10990         /* alignment */
10991         CHECK_BYTE_COUNT_SUBR(4);
10992         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10993         COUNT_BYTES_SUBR(4);
10994
10995         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10996
10997         return offset;
10998 }
10999
11000 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11001    as described in 4.2.16.10
11002 */
11003 static int
11004 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11005     int offset, guint16 *bcp, gboolean *trunc)
11006 {
11007         proto_item *item;
11008         proto_tree *tree;
11009         int old_offset;
11010         guint32 neo;
11011         smb_info_t *si = pinfo->private_data;
11012         int fn_len;
11013         const char *fn;
11014         int padcnt;
11015
11016         for (;;) {
11017                 old_offset = offset;
11018
11019                 /* next entry offset */
11020                 CHECK_BYTE_COUNT_SUBR(4);
11021                 if(parent_tree){
11022                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11023                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11024                 } else {
11025                         item = NULL;
11026                         tree = NULL;
11027                 }
11028
11029                 neo = tvb_get_letohl(tvb, offset);
11030                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11031                 COUNT_BYTES_SUBR(4);
11032
11033                 /* stream name len */
11034                 CHECK_BYTE_COUNT_SUBR(4);
11035                 fn_len = tvb_get_letohl(tvb, offset);
11036                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11037                 COUNT_BYTES_SUBR(4);
11038
11039                 /* stream size */
11040                 CHECK_BYTE_COUNT_SUBR(8);
11041                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11042                 COUNT_BYTES_SUBR(8);
11043
11044                 /* allocation size */
11045                 CHECK_BYTE_COUNT_SUBR(8);
11046                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11047                 COUNT_BYTES_SUBR(8);
11048
11049                 /* stream name */
11050                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11051                 CHECK_STRING_SUBR(fn);
11052                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11053                         fn);
11054                 COUNT_BYTES_SUBR(fn_len);
11055
11056                 proto_item_append_text(item, ": %s", fn);
11057                 proto_item_set_len(item, offset-old_offset);
11058
11059                 if (neo == 0)
11060                         break;  /* no more structures */
11061
11062                 /* skip to next structure */
11063                 padcnt = (old_offset + neo) - offset;
11064                 if (padcnt < 0) {
11065                         /*
11066                          * XXX - this is bogus; flag it?
11067                          */
11068                         padcnt = 0;
11069                 }
11070                 if (padcnt != 0) {
11071                         CHECK_BYTE_COUNT_SUBR(padcnt);
11072                         COUNT_BYTES_SUBR(padcnt);
11073                 }
11074         }
11075
11076         *trunc = FALSE;
11077         return offset;
11078 }
11079
11080 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11081    as described in 4.2.16.11
11082 */
11083 static int
11084 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11085     int offset, guint16 *bcp, gboolean *trunc)
11086 {
11087         /* compressed file size */
11088         CHECK_BYTE_COUNT_SUBR(8);
11089         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11090         COUNT_BYTES_SUBR(8);
11091
11092         /* compression format */
11093         CHECK_BYTE_COUNT_SUBR(2);
11094         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11095         COUNT_BYTES_SUBR(2);
11096
11097         /* compression unit shift */
11098         CHECK_BYTE_COUNT_SUBR(1);
11099         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11100         COUNT_BYTES_SUBR(1);
11101
11102         /* compression chunk shift */
11103         CHECK_BYTE_COUNT_SUBR(1);
11104         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11105         COUNT_BYTES_SUBR(1);
11106
11107         /* compression cluster shift */
11108         CHECK_BYTE_COUNT_SUBR(1);
11109         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11110         COUNT_BYTES_SUBR(1);
11111
11112         /* 3 reserved bytes */
11113         CHECK_BYTE_COUNT_SUBR(3);
11114         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11115         COUNT_BYTES_SUBR(3);
11116
11117         *trunc = FALSE;
11118         return offset;
11119 }
11120
11121 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11122
11123 static const value_string unix_file_type_vals[] = {
11124         { 0, "File" },
11125         { 1, "Directory" },
11126         { 2, "Symbolic link" },
11127         { 3, "Character device" },
11128         { 4, "Block device" },
11129         { 5, "FIFO" },
11130         { 6, "Socket" },
11131         { 0, NULL }
11132 };
11133
11134 static int
11135 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11136                   int offset, guint16 *bcp, gboolean *trunc)
11137 {
11138         /* End of file (file size) */
11139         CHECK_BYTE_COUNT_SUBR(8);
11140         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11141         COUNT_BYTES_SUBR(8);
11142
11143         /* Number of bytes */
11144         CHECK_BYTE_COUNT_SUBR(8);
11145         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11146         COUNT_BYTES_SUBR(8);
11147
11148         /* Last status change */
11149         CHECK_BYTE_COUNT_SUBR(8);
11150         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11151         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11152
11153         /* Last access time */
11154         CHECK_BYTE_COUNT_SUBR(8);
11155         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11156         *bcp -= 8;
11157
11158         /* Last modification time */
11159         CHECK_BYTE_COUNT_SUBR(8);
11160         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11161         *bcp -= 8;
11162
11163         /* File owner uid */
11164         CHECK_BYTE_COUNT_SUBR(8);
11165         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11166         COUNT_BYTES_SUBR(8);
11167
11168         /* File group gid */
11169         CHECK_BYTE_COUNT_SUBR(8);
11170         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11171         COUNT_BYTES_SUBR(8);
11172
11173         /* File type */
11174         CHECK_BYTE_COUNT_SUBR(4);
11175         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11176         COUNT_BYTES_SUBR(4);
11177
11178         /* Major device number */
11179         CHECK_BYTE_COUNT_SUBR(8);
11180         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11181         COUNT_BYTES_SUBR(8);
11182
11183         /* Minor device number */
11184         CHECK_BYTE_COUNT_SUBR(8);
11185         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11186         COUNT_BYTES_SUBR(8);
11187
11188         /* Unique id */
11189         CHECK_BYTE_COUNT_SUBR(8);
11190         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11191         COUNT_BYTES_SUBR(8);
11192
11193         /* Permissions */
11194         CHECK_BYTE_COUNT_SUBR(8);
11195         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11196         COUNT_BYTES_SUBR(8);
11197
11198         /* Nlinks */
11199         CHECK_BYTE_COUNT_SUBR(8);
11200         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11201         COUNT_BYTES_SUBR(8);
11202
11203         /* Sometimes there is one extra byte in the data field which I
11204            guess could be padding, but we are only using 4 or 8 byte
11205            data types so this is a bit confusing. -tpot */
11206
11207         *trunc = FALSE;
11208         return offset;
11209 }
11210
11211 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11212
11213 static int
11214 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11215                   int offset, guint16 *bcp, gboolean *trunc)
11216 {
11217         smb_info_t *si = pinfo->private_data;
11218         const char *fn;
11219         int fn_len;
11220
11221         /* Link destination */
11222
11223         fn = get_unicode_or_ascii_string(
11224                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11225
11226         CHECK_STRING_SUBR(fn);
11227         proto_tree_add_string(
11228                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11229         COUNT_BYTES_SUBR(fn_len);
11230
11231         *trunc = FALSE;
11232         return offset;
11233 }
11234
11235 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11236    as described in 4.2.19.2
11237 */
11238 static int
11239 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11240     int offset, guint16 *bcp, gboolean *trunc)
11241 {
11242         /* marked for deletion? */
11243         CHECK_BYTE_COUNT_SUBR(1);
11244         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11245         COUNT_BYTES_SUBR(1);
11246
11247         *trunc = FALSE;
11248         return offset;
11249 }
11250
11251 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11252    as described in 4.2.19.3
11253 */
11254 static int
11255 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11256     int offset, guint16 *bcp, gboolean *trunc)
11257 {
11258         /* file allocation size */
11259         CHECK_BYTE_COUNT_SUBR(8);
11260         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11261         COUNT_BYTES_SUBR(8);
11262
11263         *trunc = FALSE;
11264         return offset;
11265 }
11266
11267 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11268    as described in 4.2.19.4
11269 */
11270 static int
11271 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11272     int offset, guint16 *bcp, gboolean *trunc)
11273 {
11274         /* file end of file offset */
11275         CHECK_BYTE_COUNT_SUBR(8);
11276         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11277         COUNT_BYTES_SUBR(8);
11278
11279         *trunc = FALSE;
11280         return offset;
11281 }
11282
11283 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11284   TRANS2_QUERY_FILE_INFORMATION*/
11285 static int
11286 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11287     int offset, guint16 *bcp)
11288 {
11289         smb_info_t *si;
11290         gboolean trunc;
11291
11292         if(!*bcp){
11293                 return offset;
11294         }
11295
11296         si = (smb_info_t *)pinfo->private_data;
11297         switch(si->info_level){
11298         case 1:         /*Info Standard*/
11299                 
11300         case 2:         /*Info Query EA Size*/
11301                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11302                     &trunc);
11303                 break;
11304         case 3:         /*Info Query EAs From List*/
11305         case 4:         /*Info Query All EAs*/
11306                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11307                     &trunc);
11308                 break;
11309         case 6:         /*Info Is Name Valid*/
11310                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11311                     &trunc);
11312                 break;
11313         case 0x0101:    /*Query File Basic Info*/
11314         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11315                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11316                     &trunc);
11317                 break;
11318         case 0x0102:    /*Query File Standard Info*/
11319         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11320                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11321                     &trunc);
11322                 break;
11323         case 0x0103:    /*Query File EA Info*/
11324         case 1007:      /* SMB_FILE_EA_INFORMATION */
11325                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11326                     &trunc);
11327                 break;
11328         case 0x0104:    /*Query File Name Info*/
11329         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11330                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11331                     &trunc);
11332                 break;
11333         case 0x0107:    /*Query File All Info*/
11334         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11335                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11336                     &trunc);
11337                 break;
11338         case 0x0108:    /*Query File Alt File Info*/
11339         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11340                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11341                     &trunc);
11342                 break;
11343         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11344                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11345         case 0x0109:    /*Query File Stream Info*/
11346                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11347                     &trunc);
11348                 break;
11349         case 0x010b:    /*Query File Compression Info*/
11350         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11351                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11352                     &trunc);
11353                 break;
11354         case 0x0200:    /* Query File Unix Basic*/
11355                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11356                                            &trunc);
11357                 break;
11358         case 0x0201:    /* Query File Unix Link*/
11359                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11360                                            &trunc);
11361                 break;
11362         case 0x0202:    /* Query File Unix HardLink*/
11363                 /* XXX add this from the SNIA doc */
11364                 break;
11365         }
11366
11367         return offset;
11368 }
11369
11370 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11371   TRANS2_SET_FILE_INFORMATION*/
11372 static int
11373 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11374     int offset, guint16 *bcp)
11375 {
11376         smb_info_t *si;
11377         gboolean trunc;
11378
11379         if(!*bcp){
11380                 return offset;
11381         }
11382
11383         si = (smb_info_t *)pinfo->private_data;
11384         switch(si->info_level){
11385         case 1:         /*Info Standard*/
11386                 
11387         case 2:         /*Info Query EA Size*/
11388                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11389                     &trunc);
11390                 break;
11391         case 4:         /*Info Query All EAs*/
11392                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11393                     &trunc);
11394                 break;
11395         case 0x0101:    /*Set File Basic Info*/
11396                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11397                     &trunc);
11398                 break;
11399         case 0x0102:    /*Set File Disposition Info*/
11400                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11401                     &trunc);
11402                 break;
11403         case 0x0103:    /*Set File Allocation Info*/
11404                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11405                     &trunc);
11406                 break;
11407         case 0x0104:    /*Set End Of File Info*/
11408                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11409                     &trunc);
11410                 break;
11411         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11412                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11413                     &trunc);
11414                 break;
11415         case 0x0201:    /*Set File Unix Link.  Same as query. */
11416                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11417                     &trunc);
11418                 break;
11419         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11420                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11421                     &trunc);
11422                 break;
11423         case 1004:
11424         case 1010:
11425         case 1013:
11426         case 1014:
11427         case 1016:
11428         case 1019:
11429         case 1020:
11430         case 1023:
11431         case 1025:
11432         case 1029:
11433         case 1032:
11434         case 1039:
11435         case 1040:
11436                 /* XXX: TODO, extra levels discovered by tridge */
11437                 break;
11438         }
11439
11440         return offset;
11441 }
11442
11443
11444 static const true_false_string tfs_quota_flags_deny_disk = {
11445         "DENY DISK SPACE for users exceeding quota limit",
11446         "Do NOT deny disk space for users exceeding quota limit"
11447 };
11448 static const true_false_string tfs_quota_flags_log_limit = {
11449         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11450         "Do NOT log event when a user exceeds their quota limit"
11451 };
11452 static const true_false_string tfs_quota_flags_log_warning = {
11453         "LOG EVENT when a user exceeds their WARNING LEVEL",
11454         "Do NOT log event when a user exceeds their warning level"
11455 };
11456 static const true_false_string tfs_quota_flags_enabled = {
11457         "Quotas are ENABLED of this fs",
11458         "Quotas are NOT enabled on this fs"
11459 };
11460 static void
11461 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11462 {
11463         guint8 mask;
11464         proto_item *item = NULL;
11465         proto_tree *tree = NULL;
11466
11467         mask = tvb_get_guint8(tvb, offset);
11468
11469         if(parent_tree){
11470                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11471                         "Quota Flags: 0x%02x %s", mask,
11472                         mask?"Enabled":"Disabled");
11473                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11474         }
11475
11476         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11477                 tvb, offset, 1, mask);
11478         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11479                 tvb, offset, 1, mask);
11480         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11481                 tvb, offset, 1, mask);
11482
11483         if(mask && (!(mask&0x01))){
11484                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11485                         tvb, offset, 1, 0x01);
11486         } else {
11487                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11488                         tvb, offset, 1, mask);
11489         }
11490
11491 }
11492
11493 static int
11494 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11495 {
11496         /* first 24 bytes are unknown */
11497         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11498         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11499                     offset, 24, TRUE);
11500         COUNT_BYTES_TRANS_SUBR(24);
11501
11502         /* number of bytes for quota warning */
11503         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11504         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11505         COUNT_BYTES_TRANS_SUBR(8);
11506
11507         /* number of bytes for quota limit */
11508         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11509         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11510         COUNT_BYTES_TRANS_SUBR(8);
11511
11512         /* one byte of quota flags */
11513         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11514         dissect_quota_flags(tvb, tree, offset);
11515         COUNT_BYTES_TRANS_SUBR(1);
11516
11517         /* these 7 bytes are unknown */
11518         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11519         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11520                     offset, 7, TRUE);
11521         COUNT_BYTES_TRANS_SUBR(7);
11522
11523         return offset;
11524 }
11525
11526 static int
11527 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11528     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11529 {
11530         proto_item *item = NULL;
11531         proto_tree *tree = NULL;
11532         smb_info_t *si;
11533
11534         si = (smb_info_t *)pinfo->private_data;
11535
11536         if(parent_tree){
11537                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11538                                 "%s Data",
11539                                 val_to_str(subcmd, trans2_cmd_vals,
11540                                                 "Unknown (0x%02x)"));
11541                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11542         }
11543
11544         switch(subcmd){
11545         case 0x00:      /*TRANS2_OPEN2*/
11546                 /* XXX dont know how to decode FEAList */
11547                 break;
11548         case 0x01:      /*TRANS2_FIND_FIRST2*/
11549                 /* XXX dont know how to decode FEAList */
11550                 break;
11551         case 0x02:      /*TRANS2_FIND_NEXT2*/
11552                 /* XXX dont know how to decode FEAList */
11553                 break;
11554         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11555                 /* no data field in this request */
11556                 break;
11557         case 0x04:      /* TRANS2_SET_QUOTA */
11558                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11559                 break;
11560         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11561                 /* no data field in this request */
11562                 /*
11563                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11564                  * Extensions Version 3.0, Document Version 1.11,
11565                  * July 19, 1990" says there may be "Additional
11566                  * FileInfoLevel dependent information" here.
11567                  *
11568                  * Was that just a cut-and-pasteo?
11569                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11570                  * here.
11571                  */
11572                 break;
11573         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11574                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11575                 break;
11576         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11577                 /* no data field in this request */
11578                 /*
11579                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11580                  * Extensions Version 3.0, Document Version 1.11,
11581                  * July 19, 1990" says there may be "Additional
11582                  * FileInfoLevel dependent information" here.
11583                  *
11584                  * Was that just a cut-and-pasteo?
11585                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11586                  * here.
11587                  */
11588                 break;
11589         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11590                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11591                 break;
11592         case 0x09:      /*TRANS2_FSCTL*/
11593                 /*XXX dont know how to decode this yet */
11594
11595                 /*
11596                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11597                  * Extensions Version 3.0, Document Version 1.11,
11598                  * July 19, 1990" says this this contains a
11599                  * "File system specific data block".  (That means we
11600                  * may not be able to dissect it in any case.)
11601                  */
11602                 break;
11603         case 0x0a:      /*TRANS2_IOCTL2*/
11604                 /*XXX dont know how to decode this yet */
11605
11606                 /*
11607                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11608                  * Extensions Version 3.0, Document Version 1.11,
11609                  * July 19, 1990" says this this contains a
11610                  * "Device/function specific data block".  (That
11611                  * means we may not be able to dissect it in any case.)
11612                  */
11613                 break;
11614         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11615                 /*XXX dont know how to decode this yet */
11616
11617                 /*
11618                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11619                  * Extensions Version 3.0, Document Version 1.11,
11620                  * July 19, 1990" says this this contains "additional
11621                  * level dependent match data".
11622                  */
11623                 break;
11624         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11625                 /*XXX dont know how to decode this yet */
11626
11627                 /*
11628                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11629                  * Extensions Version 3.0, Document Version 1.11,
11630                  * July 19, 1990" says this this contains "additional
11631                  * level dependent monitor information".
11632                  */
11633                 break;
11634         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11635                 /* XXX optional FEAList, unknown what FEAList looks like*/
11636                 break;
11637         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11638                 /*XXX dont know how to decode this yet */
11639                 break;
11640         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11641                 /* no data field in this request */
11642                 break;
11643         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11644                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11645                 break;
11646         }
11647
11648         /* ooops there were data we didnt know how to process */
11649         if(dc != 0){
11650                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11651                 offset += dc;
11652         }
11653
11654         return offset;
11655 }
11656
11657
11658 static void
11659 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11660     proto_tree *tree)
11661 {
11662         int i;
11663         int offset;
11664         guint length;
11665
11666         /*
11667          * Show the setup words.
11668          */
11669         if (s_tvb != NULL) {
11670                 length = tvb_reported_length(s_tvb);
11671                 for (i = 0, offset = 0; length >= 2;
11672                     i++, offset += 2, length -= 2) {
11673                         /*
11674                          * XXX - add a setup word filterable field?
11675                          */
11676                         proto_tree_add_text(tree, s_tvb, offset, 2,
11677                             "Setup Word %d: 0x%04x", i,
11678                             tvb_get_letohs(s_tvb, offset));
11679                 }
11680         }
11681
11682         /*
11683          * Show the parameters, if any.
11684          */
11685         if (p_tvb != NULL) {
11686                 length = tvb_reported_length(p_tvb);
11687                 if (length != 0) {
11688                         proto_tree_add_text(tree, p_tvb, 0, length,
11689                             "Parameters: %s",
11690                             tvb_bytes_to_str(p_tvb, 0, length));
11691                 }
11692         }
11693
11694         /*
11695          * Show the data, if any.
11696          */
11697         if (d_tvb != NULL) {
11698                 length = tvb_reported_length(d_tvb);
11699                 if (length != 0) {
11700                         proto_tree_add_text(tree, d_tvb, 0, length,
11701                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11702                 }
11703         }
11704 }
11705
11706 /* This routine handles the following 4 calls
11707    Transaction  0x25
11708    Transaction Secondary 0x26
11709    Transaction2 0x32
11710    Transaction2 Secondary 0x33
11711 */
11712 static int
11713 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11714 {
11715         guint8 wc, sc=0;
11716         int so=offset;
11717         int sl=0;
11718         int spo=offset;
11719         int spc=0;
11720         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11721         int subcmd = -1;
11722         guint32 to;
11723         int an_len;
11724         const char *an = NULL;
11725         smb_info_t *si;
11726         smb_transact2_info_t *t2i;
11727         smb_transact_info_t *tri;
11728         guint16 bc;
11729         int padcnt;
11730         gboolean dissected_trans;
11731
11732         si = (smb_info_t *)pinfo->private_data;
11733
11734         WORD_COUNT;
11735
11736         if(wc==8){
11737                 /*secondary client request*/
11738
11739                 /* total param count, only a 16bit integer here*/
11740                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11741                 offset += 2;
11742
11743                 /* total data count , only 16bit integer here*/
11744                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11745                 offset += 2;
11746
11747                 /* param count */
11748                 pc = tvb_get_letohs(tvb, offset);
11749                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11750                 offset += 2;
11751
11752                 /* param offset */
11753                 po = tvb_get_letohs(tvb, offset);
11754                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11755                 offset += 2;
11756
11757                 /* param disp */
11758                 pd = tvb_get_letohs(tvb, offset);
11759                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11760                 offset += 2;
11761
11762                 /* data count */
11763                 dc = tvb_get_letohs(tvb, offset);
11764                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11765                 offset += 2;
11766
11767                 /* data offset */
11768                 od = tvb_get_letohs(tvb, offset);
11769                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11770                 offset += 2;
11771
11772                 /* data disp */
11773                 dd = tvb_get_letohs(tvb, offset);
11774                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11775                 offset += 2;
11776
11777                 if(si->cmd==SMB_COM_TRANSACTION2){
11778                         guint16 fid;
11779
11780                         /* fid */
11781                         fid = tvb_get_letohs(tvb, offset);
11782                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11783
11784                         offset += 2;
11785                 }
11786
11787                 /* There are no setup words. */
11788                 so = offset;
11789                 sc = 0;
11790                 sl = 0;
11791         } else {
11792                 /* it is not a secondary request */
11793
11794                 /* total param count , only a 16 bit integer here*/
11795                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11796                 offset += 2;
11797
11798                 /* total data count , only 16bit integer here*/
11799                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11800                 offset += 2;
11801
11802                 /* max param count , only 16bit integer here*/
11803                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11804                 offset += 2;
11805
11806                 /* max data count, only 16bit integer here*/
11807                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11808                 offset += 2;
11809
11810                 /* max setup count, only 16bit integer here*/
11811                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11812                 offset += 1;
11813
11814                 /* reserved byte */
11815                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11816                 offset += 1;
11817
11818                 /* transaction flags */
11819                 tf = dissect_transaction_flags(tvb, tree, offset);
11820                 offset += 2;
11821
11822                 /* timeout */
11823                 to = tvb_get_letohl(tvb, offset);
11824                 if (to == 0)
11825                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11826                 else if (to == 0xffffffff)
11827                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11828                 else
11829                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11830                 offset += 4;
11831
11832                 /* 2 reserved bytes */
11833                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11834                 offset += 2;
11835
11836                 /* param count */
11837                 pc = tvb_get_letohs(tvb, offset);
11838                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11839                 offset += 2;
11840
11841                 /* param offset */
11842                 po = tvb_get_letohs(tvb, offset);
11843                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11844                 offset += 2;
11845
11846                 /* param displacement is zero here */
11847                 pd = 0;
11848
11849                 /* data count */
11850                 dc = tvb_get_letohs(tvb, offset);
11851                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11852                 offset += 2;
11853
11854                 /* data offset */
11855                 od = tvb_get_letohs(tvb, offset);
11856                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11857                 offset += 2;
11858
11859                 /* data displacement is zero here */
11860                 dd = 0;
11861
11862                 /* setup count */
11863                 sc = tvb_get_guint8(tvb, offset);
11864                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11865                 offset += 1;
11866
11867                 /* reserved byte */
11868                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11869                 offset += 1;
11870
11871                 /* this is where the setup bytes, if any start */
11872                 so = offset;
11873                 sl = sc*2;
11874
11875                 /* if there were any setup bytes, decode them */
11876                 if(sc){
11877                         switch(si->cmd){
11878
11879                         case SMB_COM_TRANSACTION2:
11880                                 /* TRANSACTION2 only has one setup word and
11881                                    that is the subcommand code.
11882
11883                                    XXX - except for TRANS2_FSCTL
11884                                    and TRANS2_IOCTL. */
11885                                 subcmd = tvb_get_letohs(tvb, offset);
11886                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11887                                     tvb, offset, 2, subcmd);
11888                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11889                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11890                                             val_to_str(subcmd, trans2_cmd_vals,
11891                                                 "Unknown (0x%02x)"));
11892                                 }
11893                                 if (!si->unidir) {
11894                                         if(!pinfo->fd->flags.visited){
11895                                                 /*
11896                                                  * Allocate a new
11897                                                  * smb_transact2_info_t
11898                                                  * structure.
11899                                                  */
11900                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11901                                                 t2i->subcmd = subcmd;
11902                                                 t2i->info_level = -1;
11903                                                 t2i->resume_keys = FALSE;
11904                                                 si->sip->extra_info = t2i;
11905                                         }
11906                                 }
11907
11908                                 /*
11909                                  * XXX - process TRANS2_FSCTL and
11910                                  * TRANS2_IOCTL setup words here.
11911                                  */
11912                                 break;
11913
11914                         case SMB_COM_TRANSACTION:
11915                                 /* TRANSACTION setup words processed below */
11916                                 break;
11917                         }
11918
11919                         offset += sl;
11920                 }
11921         }
11922
11923         BYTE_COUNT;
11924
11925         if(wc!=8){
11926                 /* primary request */
11927                 /* name is NULL if transaction2 */
11928                 if(si->cmd == SMB_COM_TRANSACTION){
11929                         /* Transaction Name */
11930                         an = get_unicode_or_ascii_string(tvb, &offset,
11931                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11932                         if (an == NULL)
11933                                 goto endofcommand;
11934                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11935                                 offset, an_len, an);
11936                         COUNT_BYTES(an_len);
11937                 }
11938         }
11939
11940         /*
11941          * The pipe or mailslot arguments for Transaction start with
11942          * the first setup word (or where the first setup word would
11943          * be if there were any setup words), and run to the current
11944          * offset (which could mean that there aren't any).
11945          */
11946         spo = so;
11947         spc = offset - spo;
11948
11949         /* parameters */
11950         if(po>offset){
11951                 /* We have some initial padding bytes.
11952                 */
11953                 padcnt = po-offset;
11954                 if (padcnt > bc)
11955                         padcnt = bc;
11956                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11957                 COUNT_BYTES(padcnt);
11958         }
11959         if(pc){
11960                 CHECK_BYTE_COUNT(pc);
11961                 switch(si->cmd) {
11962
11963                 case SMB_COM_TRANSACTION2:
11964                         /* TRANSACTION2 parameters*/
11965                         offset = dissect_transaction2_request_parameters(tvb,
11966                             pinfo, tree, offset, subcmd, pc);
11967                         bc -= pc;
11968                         break;
11969
11970                 case SMB_COM_TRANSACTION:
11971                         /* TRANSACTION parameters processed below */
11972                         COUNT_BYTES(pc);
11973                         break;
11974                 }
11975         }
11976
11977         /* data */
11978         if(od>offset){
11979                 /* We have some initial padding bytes.
11980                 */
11981                 padcnt = od-offset;
11982                 if (padcnt > bc)
11983                         padcnt = bc;
11984                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11985                 COUNT_BYTES(padcnt);
11986         }
11987         if(dc){
11988                 CHECK_BYTE_COUNT(dc);
11989                 switch(si->cmd){
11990
11991                 case SMB_COM_TRANSACTION2:
11992                         /* TRANSACTION2 data*/
11993                         offset = dissect_transaction2_request_data(tvb, pinfo,
11994                             tree, offset, subcmd, dc);
11995                         bc -= dc;
11996                         break;
11997
11998                 case SMB_COM_TRANSACTION:
11999                         /* TRANSACTION data processed below */
12000                         COUNT_BYTES(dc);
12001                         break;
12002                 }
12003         }
12004
12005         /*TRANSACTION request parameters */
12006         if(si->cmd==SMB_COM_TRANSACTION){
12007                 /*XXX replace this block with a function and use that one
12008                      for both requests/responses*/
12009                 if(dd==0){
12010                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12011                         tvbuff_t *sp_tvb, *pd_tvb;
12012
12013                         if(pc>0){
12014                                 if(pc>tvb_length_remaining(tvb, po)){
12015                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12016                                 } else {
12017                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12018                                 }
12019                         } else {
12020                                 p_tvb = NULL;
12021                         }
12022                         if(dc>0){
12023                                 if(dc>tvb_length_remaining(tvb, od)){
12024                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12025                                 } else {
12026                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12027                                 }
12028                         } else {
12029                                 d_tvb = NULL;
12030                         }
12031                         if(sl){
12032                                 if(sl>tvb_length_remaining(tvb, so)){
12033                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12034                                 } else {
12035                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12036                                 }
12037                         } else {
12038                                 s_tvb = NULL;
12039                         }
12040
12041                         if (!si->unidir) {
12042                                 if(!pinfo->fd->flags.visited){
12043                                         /*
12044                                          * Allocate a new smb_transact_info_t
12045                                          * structure.
12046                                          */
12047                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12048                                         tri->subcmd = -1;
12049                                         tri->trans_subcmd = -1;
12050                                         tri->function = -1;
12051                                         tri->fid = -1;
12052                                         tri->lanman_cmd = 0;
12053                                         tri->param_descrip = NULL;
12054                                         tri->data_descrip = NULL;
12055                                         tri->aux_data_descrip = NULL;
12056                                         tri->info_level = -1;
12057                                         si->sip->extra_info = tri;
12058                                 } else {
12059                                         /*
12060                                          * We already filled the structure
12061                                          * in; don't bother doing so again.
12062                                          */
12063                                         tri = NULL;
12064                                 }
12065                         } else {
12066                                 /*
12067                                  * This is a unidirectional message, for
12068                                  * which there will be no reply; don't
12069                                  * bother allocating an "smb_transact_info_t"
12070                                  * structure for it.
12071                                  */
12072                                 tri = NULL;
12073                         }
12074                         dissected_trans = FALSE;
12075                         if(strncmp("\\PIPE\\", an, 6) == 0){
12076                                 if (tri != NULL)
12077                                         tri->subcmd=TRANSACTION_PIPE;
12078
12079                                 /*
12080                                  * A tvbuff containing the setup words and
12081                                  * the pipe path.
12082                                  */
12083                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12084
12085                                 /*
12086                                  * A tvbuff containing the parameters and the
12087                                  * data.
12088                                  */
12089                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12090
12091                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12092                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12093                                     top_tree);
12094
12095                                 /* In case we did not see the TreeConnect call,
12096                                    store this TID here as well as a IPC TID 
12097                                    so we know that future Read/Writes to this 
12098                                    TID is (probably) DCERPC.
12099                                 */
12100                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12101                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12102                                 }
12103                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12104                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12105                                 if (tri != NULL)
12106                                         tri->subcmd=TRANSACTION_MAILSLOT;
12107
12108                                 /*
12109                                  * A tvbuff containing the setup words and
12110                                  * the mailslot path.
12111                                  */
12112                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12113                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12114                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12115                         }
12116                         if (!dissected_trans)
12117                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12118                 } else {
12119                         if(check_col(pinfo->cinfo, COL_INFO)){
12120                                 col_append_str(pinfo->cinfo, COL_INFO,
12121                                         "[transact continuation]");
12122                         }
12123                 }
12124         }
12125
12126         END_OF_SMB
12127
12128         return offset;
12129 }
12130
12131
12132
12133 static int
12134 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12135     int offset, guint16 *bcp, gboolean *trunc)
12136 {
12137         int fn_len;
12138         const char *fn;
12139         int old_offset = offset;
12140         proto_item *item = NULL;
12141         proto_tree *tree = NULL;
12142         smb_info_t *si;
12143         smb_transact2_info_t *t2i;
12144         gboolean resume_keys = FALSE;
12145
12146         si = (smb_info_t *)pinfo->private_data;
12147         if (si->sip != NULL) {
12148                 t2i = si->sip->extra_info;
12149                 if (t2i != NULL)
12150                         resume_keys = t2i->resume_keys;
12151         }
12152
12153         if(parent_tree){
12154                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12155                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12156                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12157         }
12158
12159         if (resume_keys) {
12160                 /* resume key */
12161                 CHECK_BYTE_COUNT_SUBR(4);
12162                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12163                 COUNT_BYTES_SUBR(4);
12164         }
12165
12166         /* create time */
12167         CHECK_BYTE_COUNT_SUBR(4);
12168         offset = dissect_smb_datetime(tvb, tree, offset,
12169                 hf_smb_create_time,
12170                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12171         *bcp -= 4;
12172
12173         /* access time */
12174         CHECK_BYTE_COUNT_SUBR(4);
12175         offset = dissect_smb_datetime(tvb, tree, offset,
12176                 hf_smb_access_time,
12177                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12178         *bcp -= 4;
12179
12180         /* last write time */
12181         CHECK_BYTE_COUNT_SUBR(4);
12182         offset = dissect_smb_datetime(tvb, tree, offset,
12183                 hf_smb_last_write_time,
12184                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12185         *bcp -= 4;
12186
12187         /* data size */
12188         CHECK_BYTE_COUNT_SUBR(4);
12189         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12190         COUNT_BYTES_SUBR(4);
12191
12192         /* allocation size */
12193         CHECK_BYTE_COUNT_SUBR(4);
12194         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12195         COUNT_BYTES_SUBR(4);
12196
12197         /* File Attributes */
12198         CHECK_BYTE_COUNT_SUBR(2);
12199         offset = dissect_file_attributes(tvb, tree, offset, 2);
12200         *bcp -= 2;
12201
12202         /* file name len */
12203         CHECK_BYTE_COUNT_SUBR(1);
12204         fn_len = tvb_get_guint8(tvb, offset);
12205         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12206         COUNT_BYTES_SUBR(1);
12207         if (si->unicode)
12208                 fn_len += 2;    /* include terminating '\0' */
12209         else
12210                 fn_len++;       /* include terminating '\0' */
12211
12212         /* file name */
12213         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12214         CHECK_STRING_SUBR(fn);
12215         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12216                 fn);
12217         COUNT_BYTES_SUBR(fn_len);
12218
12219         if (check_col(pinfo->cinfo, COL_INFO)) {
12220                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12221                 fn);
12222         }
12223
12224         proto_item_append_text(item, " File: %s", fn);
12225         proto_item_set_len(item, offset-old_offset);
12226
12227         *trunc = FALSE;
12228         return offset;
12229 }
12230
12231 static int
12232 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12233     int offset, guint16 *bcp, gboolean *trunc)
12234 {
12235         int fn_len;
12236         const char *fn;
12237         int old_offset = offset;
12238         proto_item *item = NULL;
12239         proto_tree *tree = NULL;
12240         smb_info_t *si;
12241         smb_transact2_info_t *t2i;
12242         gboolean resume_keys = FALSE;
12243
12244         si = (smb_info_t *)pinfo->private_data;
12245         if (si->sip != NULL) {
12246                 t2i = si->sip->extra_info;
12247                 if (t2i != NULL)
12248                         resume_keys = t2i->resume_keys;
12249         }
12250
12251         if(parent_tree){
12252                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12253                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12254                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12255         }
12256
12257         if (resume_keys) {
12258                 /* resume key */
12259                 CHECK_BYTE_COUNT_SUBR(4);
12260                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12261                 COUNT_BYTES_SUBR(4);
12262         }
12263
12264         /* create time */
12265         CHECK_BYTE_COUNT_SUBR(4);
12266         offset = dissect_smb_datetime(tvb, tree, offset,
12267                 hf_smb_create_time,
12268                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12269         *bcp -= 4;
12270
12271         /* access time */
12272         CHECK_BYTE_COUNT_SUBR(4);
12273         offset = dissect_smb_datetime(tvb, tree, offset,
12274                 hf_smb_access_time,
12275                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12276         *bcp -= 4;
12277
12278         /* last write time */
12279         CHECK_BYTE_COUNT_SUBR(4);
12280         offset = dissect_smb_datetime(tvb, tree, offset,
12281                 hf_smb_last_write_time,
12282                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12283         *bcp -= 4;
12284
12285         /* data size */
12286         CHECK_BYTE_COUNT_SUBR(4);
12287         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12288         COUNT_BYTES_SUBR(4);
12289
12290         /* allocation size */
12291         CHECK_BYTE_COUNT_SUBR(4);
12292         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12293         COUNT_BYTES_SUBR(4);
12294
12295         /* File Attributes */
12296         CHECK_BYTE_COUNT_SUBR(2);
12297         offset = dissect_file_attributes(tvb, tree, offset, 2);
12298         *bcp -= 2;
12299
12300         /* ea length */
12301         CHECK_BYTE_COUNT_SUBR(4);
12302         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12303         COUNT_BYTES_SUBR(4);
12304
12305         /* file name len */
12306         CHECK_BYTE_COUNT_SUBR(1);
12307         fn_len = tvb_get_guint8(tvb, offset);
12308         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12309         COUNT_BYTES_SUBR(1);
12310         if (si->unicode)
12311                 fn_len += 2;    /* include terminating '\0' */
12312         else
12313                 fn_len++;       /* include terminating '\0' */
12314
12315         /* file name */
12316         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12317         CHECK_STRING_SUBR(fn);
12318         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12319                 fn);
12320         COUNT_BYTES_SUBR(fn_len);
12321
12322         if (check_col(pinfo->cinfo, COL_INFO)) {
12323                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12324                 fn);
12325         }
12326
12327         proto_item_append_text(item, " File: %s", fn);
12328         proto_item_set_len(item, offset-old_offset);
12329
12330         *trunc = FALSE;
12331         return offset;
12332 }
12333
12334 static int
12335 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12336     int offset, guint16 *bcp, gboolean *trunc)
12337 {
12338         int fn_len;
12339         const char *fn;
12340         int old_offset = offset;
12341         proto_item *item = NULL;
12342         proto_tree *tree = NULL;
12343         smb_info_t *si;
12344         guint32 neo;
12345         int padcnt;
12346
12347         si = (smb_info_t *)pinfo->private_data;
12348
12349         if(parent_tree){
12350                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12351                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12352                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12353         }
12354
12355         /*
12356          * We assume that the presence of a next entry offset implies the
12357          * absence of a resume key, as appears to be the case for 4.3.4.6.
12358          */
12359
12360         /* next entry offset */
12361         CHECK_BYTE_COUNT_SUBR(4);
12362         neo = tvb_get_letohl(tvb, offset);
12363         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12364         COUNT_BYTES_SUBR(4);
12365
12366         /* file index */
12367         CHECK_BYTE_COUNT_SUBR(4);
12368         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12369         COUNT_BYTES_SUBR(4);
12370
12371         /* create time */
12372         CHECK_BYTE_COUNT_SUBR(8);
12373         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12374         *bcp -= 8;
12375
12376         /* access time */
12377         CHECK_BYTE_COUNT_SUBR(8);
12378         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12379         *bcp -= 8;
12380
12381         /* last write time */
12382         CHECK_BYTE_COUNT_SUBR(8);
12383         offset = dissect_smb_64bit_time(tvb, tree, offset,
12384                 hf_smb_last_write_time);
12385         *bcp -= 8;
12386
12387         /* last change time */
12388         CHECK_BYTE_COUNT_SUBR(8);
12389         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12390         *bcp -= 8;
12391
12392         /* end of file */
12393         CHECK_BYTE_COUNT_SUBR(8);
12394         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12395         COUNT_BYTES_SUBR(8);
12396
12397         /* allocation size */
12398         CHECK_BYTE_COUNT_SUBR(8);
12399         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12400         COUNT_BYTES_SUBR(8);
12401
12402         /* Extended File Attributes */
12403         CHECK_BYTE_COUNT_SUBR(4);
12404         offset = dissect_file_ext_attr(tvb, tree, offset);
12405         *bcp -= 4;
12406
12407         /* file name len */
12408         CHECK_BYTE_COUNT_SUBR(4);
12409         fn_len = tvb_get_letohl(tvb, offset);
12410         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12411         COUNT_BYTES_SUBR(4);
12412
12413         /* file name */
12414         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12415         CHECK_STRING_SUBR(fn);
12416         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12417                 fn);
12418         COUNT_BYTES_SUBR(fn_len);
12419
12420         if (check_col(pinfo->cinfo, COL_INFO)) {
12421                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12422                 fn);
12423         }
12424
12425         /* skip to next structure */
12426         if(neo){
12427                 padcnt = (old_offset + neo) - offset;
12428                 if (padcnt < 0) {
12429                         /*
12430                          * XXX - this is bogus; flag it?
12431                          */
12432                         padcnt = 0;
12433                 }
12434                 if (padcnt != 0) {
12435                         CHECK_BYTE_COUNT_SUBR(padcnt);
12436                         COUNT_BYTES_SUBR(padcnt);
12437                 }
12438         }
12439
12440         proto_item_append_text(item, " File: %s", fn);
12441         proto_item_set_len(item, offset-old_offset);
12442
12443         *trunc = FALSE;
12444         return offset;
12445 }
12446
12447 static int
12448 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12449     int offset, guint16 *bcp, gboolean *trunc)
12450 {
12451         int fn_len;
12452         const char *fn;
12453         int old_offset = offset;
12454         proto_item *item = NULL;
12455         proto_tree *tree = NULL;
12456         smb_info_t *si;
12457         guint32 neo;
12458         int padcnt;
12459
12460         si = (smb_info_t *)pinfo->private_data;
12461
12462         if(parent_tree){
12463                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12464                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12465                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12466         }
12467
12468         /*
12469          * We assume that the presence of a next entry offset implies the
12470          * absence of a resume key, as appears to be the case for 4.3.4.6.
12471          */
12472
12473         /* next entry offset */
12474         CHECK_BYTE_COUNT_SUBR(4);
12475         neo = tvb_get_letohl(tvb, offset);
12476         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12477         COUNT_BYTES_SUBR(4);
12478
12479         /* file index */
12480         CHECK_BYTE_COUNT_SUBR(4);
12481         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12482         COUNT_BYTES_SUBR(4);
12483
12484         /* create time */
12485         CHECK_BYTE_COUNT_SUBR(8);
12486         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12487         *bcp -= 8;
12488
12489         /* access time */
12490         CHECK_BYTE_COUNT_SUBR(8);
12491         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12492         *bcp -= 8;
12493
12494         /* last write time */
12495         CHECK_BYTE_COUNT_SUBR(8);
12496         offset = dissect_smb_64bit_time(tvb, tree, offset,
12497                 hf_smb_last_write_time);
12498         *bcp -= 8;
12499
12500         /* last change time */
12501         CHECK_BYTE_COUNT_SUBR(8);
12502         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12503         *bcp -= 8;
12504
12505         /* end of file */
12506         CHECK_BYTE_COUNT_SUBR(8);
12507         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12508         COUNT_BYTES_SUBR(8);
12509
12510         /* allocation size */
12511         CHECK_BYTE_COUNT_SUBR(8);
12512         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12513         COUNT_BYTES_SUBR(8);
12514
12515         /* Extended File Attributes */
12516         CHECK_BYTE_COUNT_SUBR(4);
12517         offset = dissect_file_ext_attr(tvb, tree, offset);
12518         *bcp -= 4;
12519
12520         /* file name len */
12521         CHECK_BYTE_COUNT_SUBR(4);
12522         fn_len = tvb_get_letohl(tvb, offset);
12523         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12524         COUNT_BYTES_SUBR(4);
12525
12526         /* ea length */
12527         CHECK_BYTE_COUNT_SUBR(4);
12528         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12529         COUNT_BYTES_SUBR(4);
12530
12531         /* file name */
12532         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12533         CHECK_STRING_SUBR(fn);
12534         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12535                 fn);
12536         COUNT_BYTES_SUBR(fn_len);
12537
12538         if (check_col(pinfo->cinfo, COL_INFO)) {
12539                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12540                 fn);
12541         }
12542
12543         /* skip to next structure */
12544         if(neo){
12545                 padcnt = (old_offset + neo) - offset;
12546                 if (padcnt < 0) {
12547                         /*
12548                          * XXX - this is bogus; flag it?
12549                          */
12550                         padcnt = 0;
12551                 }
12552                 if (padcnt != 0) {
12553                         CHECK_BYTE_COUNT_SUBR(padcnt);
12554                         COUNT_BYTES_SUBR(padcnt);
12555                 }
12556         }
12557
12558         proto_item_append_text(item, " File: %s", fn);
12559         proto_item_set_len(item, offset-old_offset);
12560
12561         *trunc = FALSE;
12562         return offset;
12563 }
12564
12565 static int
12566 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12567     int offset, guint16 *bcp, gboolean *trunc)
12568 {
12569         int fn_len, sfn_len;
12570         const char *fn, *sfn;
12571         int old_offset = offset;
12572         proto_item *item = NULL;
12573         proto_tree *tree = NULL;
12574         smb_info_t *si;
12575         guint32 neo;
12576         int padcnt;
12577
12578         si = (smb_info_t *)pinfo->private_data;
12579
12580         if(parent_tree){
12581                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12582                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12583                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12584         }
12585
12586         /*
12587          * XXX - I have not seen any of these that contain a resume
12588          * key, even though some of the requests had the "return resume
12589          * key" flag set.
12590          */
12591
12592         /* next entry offset */
12593         CHECK_BYTE_COUNT_SUBR(4);
12594         neo = tvb_get_letohl(tvb, offset);
12595         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12596         COUNT_BYTES_SUBR(4);
12597
12598         /* file index */
12599         CHECK_BYTE_COUNT_SUBR(4);
12600         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12601         COUNT_BYTES_SUBR(4);
12602
12603         /* create time */
12604         CHECK_BYTE_COUNT_SUBR(8);
12605         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12606         *bcp -= 8;
12607
12608         /* access time */
12609         CHECK_BYTE_COUNT_SUBR(8);
12610         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12611         *bcp -= 8;
12612
12613         /* last write time */
12614         CHECK_BYTE_COUNT_SUBR(8);
12615         offset = dissect_smb_64bit_time(tvb, tree, offset,
12616                 hf_smb_last_write_time);
12617         *bcp -= 8;
12618
12619         /* last change time */
12620         CHECK_BYTE_COUNT_SUBR(8);
12621         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12622         *bcp -= 8;
12623
12624         /* end of file */
12625         CHECK_BYTE_COUNT_SUBR(8);
12626         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12627         COUNT_BYTES_SUBR(8);
12628
12629         /* allocation size */
12630         CHECK_BYTE_COUNT_SUBR(8);
12631         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12632         COUNT_BYTES_SUBR(8);
12633
12634         /* Extended File Attributes */
12635         CHECK_BYTE_COUNT_SUBR(4);
12636         offset = dissect_file_ext_attr(tvb, tree, offset);
12637         *bcp -= 4;
12638
12639         /* file name len */
12640         CHECK_BYTE_COUNT_SUBR(4);
12641         fn_len = tvb_get_letohl(tvb, offset);
12642         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12643         COUNT_BYTES_SUBR(4);
12644
12645         /*
12646          * EA length.
12647          *
12648          * XXX - in one captures, this has the topmost bit set, and the
12649          * rest of the bits have the value 7.  Is the topmost bit being
12650          * set some indication that the value *isn't* the length of
12651          * the EAs?
12652          */
12653         CHECK_BYTE_COUNT_SUBR(4);
12654         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12655         COUNT_BYTES_SUBR(4);
12656
12657         /* short file name len */
12658         CHECK_BYTE_COUNT_SUBR(1);
12659         sfn_len = tvb_get_guint8(tvb, offset);
12660         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12661         COUNT_BYTES_SUBR(1);
12662
12663         /* reserved byte */
12664         CHECK_BYTE_COUNT_SUBR(1);
12665         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12666         COUNT_BYTES_SUBR(1);
12667
12668         /* short file name */
12669         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12670         CHECK_STRING_SUBR(sfn);
12671         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12672                 sfn);
12673         COUNT_BYTES_SUBR(24);
12674
12675         /* file name */
12676         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12677         CHECK_STRING_SUBR(fn);
12678         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12679                 fn);
12680         COUNT_BYTES_SUBR(fn_len);
12681
12682         if (check_col(pinfo->cinfo, COL_INFO)) {
12683                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12684                 fn);
12685         }
12686
12687         /* skip to next structure */
12688         if(neo){
12689                 padcnt = (old_offset + neo) - offset;
12690                 if (padcnt < 0) {
12691                         /*
12692                          * XXX - this is bogus; flag it?
12693                          */
12694                         padcnt = 0;
12695                 }
12696                 if (padcnt != 0) {
12697                         CHECK_BYTE_COUNT_SUBR(padcnt);
12698                         COUNT_BYTES_SUBR(padcnt);
12699                 }
12700         }
12701
12702         proto_item_append_text(item, " File: %s", fn);
12703         proto_item_set_len(item, offset-old_offset);
12704
12705         *trunc = FALSE;
12706         return offset;
12707 }
12708
12709 static int
12710 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12711     int offset, guint16 *bcp, gboolean *trunc)
12712 {
12713         int fn_len;
12714         const char *fn;
12715         int old_offset = offset;
12716         proto_item *item = NULL;
12717         proto_tree *tree = NULL;
12718         smb_info_t *si;
12719         guint32 neo;
12720         int padcnt;
12721
12722         si = (smb_info_t *)pinfo->private_data;
12723
12724         if(parent_tree){
12725                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12726                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12727                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12728         }
12729
12730         /*
12731          * We assume that the presence of a next entry offset implies the
12732          * absence of a resume key, as appears to be the case for 4.3.4.6.
12733          */
12734
12735         /* next entry offset */
12736         CHECK_BYTE_COUNT_SUBR(4);
12737         neo = tvb_get_letohl(tvb, offset);
12738         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12739         COUNT_BYTES_SUBR(4);
12740
12741         /* file index */
12742         CHECK_BYTE_COUNT_SUBR(4);
12743         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12744         COUNT_BYTES_SUBR(4);
12745
12746         /* file name len */
12747         CHECK_BYTE_COUNT_SUBR(4);
12748         fn_len = tvb_get_letohl(tvb, offset);
12749         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12750         COUNT_BYTES_SUBR(4);
12751
12752         /* file name */
12753         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12754         CHECK_STRING_SUBR(fn);
12755         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12756                 fn);
12757         COUNT_BYTES_SUBR(fn_len);
12758
12759         if (check_col(pinfo->cinfo, COL_INFO)) {
12760                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12761                 fn);
12762         }
12763
12764         /* skip to next structure */
12765         if(neo){
12766                 padcnt = (old_offset + neo) - offset;
12767                 if (padcnt < 0) {
12768                         /*
12769                          * XXX - this is bogus; flag it?
12770                          */
12771                         padcnt = 0;
12772                 }
12773                 if (padcnt != 0) {
12774                         CHECK_BYTE_COUNT_SUBR(padcnt);
12775                         COUNT_BYTES_SUBR(padcnt);
12776                 }
12777         }
12778
12779         proto_item_append_text(item, " File: %s", fn);
12780         proto_item_set_len(item, offset-old_offset);
12781
12782         *trunc = FALSE;
12783         return offset;
12784 }
12785
12786 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12787
12788 static int
12789 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12790                 proto_tree *tree, int offset, guint16 *bcp,
12791                 gboolean *trunc)
12792 {
12793         smb_info_t *si = pinfo->private_data;
12794         const char *fn;
12795         int fn_len;
12796
12797         /* NextEntryOffset */
12798         CHECK_BYTE_COUNT_SUBR(4);
12799         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
12800         COUNT_BYTES_SUBR(4);
12801         
12802         /* ResumeKey */
12803         CHECK_BYTE_COUNT_SUBR(4);
12804         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
12805         COUNT_BYTES_SUBR(4);
12806
12807         /* End of file (file size) */
12808         CHECK_BYTE_COUNT_SUBR(8);
12809         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
12810         COUNT_BYTES_SUBR(8);
12811
12812         /* Number of bytes */
12813         CHECK_BYTE_COUNT_SUBR(8);
12814         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
12815         COUNT_BYTES_SUBR(8);
12816
12817         /* Last status change */
12818         CHECK_BYTE_COUNT_SUBR(8);
12819         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12820         COUNT_BYTES_SUBR(8);
12821
12822         /* Last access time */
12823         CHECK_BYTE_COUNT_SUBR(8);
12824         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12825         COUNT_BYTES_SUBR(8);
12826
12827         /* Last modification time */
12828         CHECK_BYTE_COUNT_SUBR(8);
12829         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12830         COUNT_BYTES_SUBR(8);
12831
12832         /* File owner uid */
12833         CHECK_BYTE_COUNT_SUBR(8);
12834         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
12835         COUNT_BYTES_SUBR(8);
12836
12837         /* File group gid */
12838         CHECK_BYTE_COUNT_SUBR(8);
12839         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
12840         COUNT_BYTES_SUBR(8);
12841
12842         /* File type */
12843         CHECK_BYTE_COUNT_SUBR(4);
12844         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
12845         COUNT_BYTES_SUBR(4);
12846
12847         /* Major device number */
12848         CHECK_BYTE_COUNT_SUBR(8);
12849         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
12850         COUNT_BYTES_SUBR(8);
12851
12852         /* Minor device number */
12853         CHECK_BYTE_COUNT_SUBR(8);
12854         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12855         COUNT_BYTES_SUBR(8);
12856
12857         /* Unique id */
12858         CHECK_BYTE_COUNT_SUBR(8);
12859         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12860         COUNT_BYTES_SUBR(8);
12861
12862         /* Permissions */
12863         CHECK_BYTE_COUNT_SUBR(8);
12864         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12865         COUNT_BYTES_SUBR(8);
12866
12867         /* Nlinks */
12868         CHECK_BYTE_COUNT_SUBR(8);
12869         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12870         COUNT_BYTES_SUBR(8);
12871
12872         /* Name */
12873
12874         fn = get_unicode_or_ascii_string(
12875                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12876
12877         CHECK_STRING_SUBR(fn);
12878         proto_tree_add_string(
12879                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12880         COUNT_BYTES_SUBR(fn_len);
12881
12882         *trunc = FALSE;
12883         return offset;
12884 }
12885
12886 /*dissect the data block for TRANS2_FIND_FIRST2*/
12887 static int
12888 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12889     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12890 {
12891         smb_info_t *si;
12892
12893         if(!*bcp){
12894                 return offset;
12895         }
12896
12897         si = (smb_info_t *)pinfo->private_data;
12898         switch(si->info_level){
12899         case 1:         /*Info Standard*/
12900                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12901                     trunc);
12902                 break;
12903         case 2:         /*Info Query EA Size*/
12904                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12905                     trunc);
12906                 break;
12907         case 3:         /*Info Query EAs From List same as
12908                                 InfoQueryEASize*/
12909                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12910                     trunc);
12911                 break;
12912         case 0x0101:    /*Find File Directory Info*/
12913                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12914                     trunc);
12915                 break;
12916         case 0x0102:    /*Find File Full Directory Info*/
12917                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12918                     trunc);
12919                 break;
12920         case 0x0103:    /*Find File Names Info*/
12921                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12922                     trunc);
12923                 break;
12924         case 0x0104:    /*Find File Both Directory Info*/
12925                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12926                     trunc);
12927                 break;
12928         case 0x0202:    /*Find File UNIX*/
12929                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12930                     trunc);
12931                 break;
12932         default:        /* unknown info level */
12933                 *trunc = FALSE;
12934                 break;
12935         }
12936         return offset;
12937 }
12938
12939
12940 static int
12941 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12942 {
12943         guint32 mask;
12944         proto_item *item = NULL;
12945         proto_tree *tree = NULL;
12946
12947         mask = tvb_get_letohl(tvb, offset);
12948
12949         if(parent_tree){
12950                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12951                         "FS Attributes: 0x%08x", mask);
12952                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12953         }
12954
12955         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12956                 tvb, offset, 4, mask);
12957         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12958                 tvb, offset, 4, mask);
12959         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12960                 tvb, offset, 4, mask);
12961         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12962                 tvb, offset, 4, mask);
12963         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12964                 tvb, offset, 4, mask);
12965         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12966                 tvb, offset, 4, mask);
12967         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12968                 tvb, offset, 4, mask);
12969
12970         offset += 4;
12971         return offset;
12972 }
12973
12974
12975 static int
12976 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12977 {
12978         guint32 mask;
12979         proto_item *item = NULL;
12980         proto_tree *tree = NULL;
12981
12982         mask = tvb_get_letohl(tvb, offset);
12983
12984         if(parent_tree){
12985                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12986                         "Device Characteristics: 0x%08x", mask);
12987                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12988         }
12989
12990         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12991                 tvb, offset, 4, mask);
12992         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12993                 tvb, offset, 4, mask);
12994         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12995                 tvb, offset, 4, mask);
12996         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12997                 tvb, offset, 4, mask);
12998         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12999                 tvb, offset, 4, mask);
13000         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13001                 tvb, offset, 4, mask);
13002         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13003                 tvb, offset, 4, mask);
13004
13005         offset += 4;
13006         return offset;
13007 }
13008
13009 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13010
13011 static const true_false_string tfs_smb_mac_access_ctrl = {
13012   "Macintosh Access Control Supported",
13013   "Macintosh Access Control Not Supported"
13014 };
13015
13016 static const true_false_string tfs_smb_mac_getset_comments = {
13017   "Macintosh Get & Set Comments Supported",
13018   "Macintosh Get & Set Comments Not Supported"
13019 };
13020
13021 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13022   "Macintosh Get & Set Desktop Database Info Supported",
13023   "Macintosh Get & Set Desktop Database Info Supported"
13024 };
13025
13026 static const true_false_string tfs_smb_mac_unique_ids = {
13027   "Macintosh Unique IDs Supported",
13028   "Macintosh Unique IDs Not Supported"
13029 };
13030
13031 static const true_false_string tfs_smb_mac_streams = {
13032   "Macintosh and Streams Extensions Not Supported",
13033   "Macintosh and Streams Extensions Supported"
13034 };
13035
13036 static int
13037 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13038     int offset, guint16 *bcp)
13039 {
13040         smb_info_t *si;
13041         int fn_len, vll, fnl;
13042         const char *fn;
13043         guint support = 0;
13044         proto_item *item = NULL;
13045         proto_tree *ti = NULL;
13046
13047         if(!*bcp){
13048                 return offset;
13049         }
13050
13051         si = (smb_info_t *)pinfo->private_data;
13052         switch(si->info_level){
13053         case 1:         /* SMB_INFO_ALLOCATION */
13054                 /* filesystem id */
13055                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13056                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13057                 COUNT_BYTES_TRANS_SUBR(4);
13058
13059                 /* sectors per unit */
13060                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13061                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13062                 COUNT_BYTES_TRANS_SUBR(4);
13063
13064                 /* units */
13065                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13066                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13067                 COUNT_BYTES_TRANS_SUBR(4);
13068
13069                 /* avail units */
13070                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13071                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13072                 COUNT_BYTES_TRANS_SUBR(4);
13073
13074                 /* bytes per sector, only 16bit integer here */
13075                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13076                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13077                 COUNT_BYTES_TRANS_SUBR(2);
13078
13079                 break;
13080         case 2:         /* SMB_INFO_VOLUME */
13081                 /* volume serial number */
13082                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13083                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13084                 COUNT_BYTES_TRANS_SUBR(4);
13085
13086                 /* volume label length, only one byte here */
13087                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13088                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13089                 COUNT_BYTES_TRANS_SUBR(1);
13090
13091                 /* label */
13092                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13093                 CHECK_STRING_TRANS_SUBR(fn);
13094                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13095                         fn);
13096                 COUNT_BYTES_TRANS_SUBR(fn_len);
13097
13098                 break;
13099         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13100         case 1001:      /* SMB_FS_LABEL_INFORMATION */
13101                 /* volume label length */
13102                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13103                 vll = tvb_get_letohl(tvb, offset);
13104                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13105                 COUNT_BYTES_TRANS_SUBR(4);
13106
13107                 /* label */
13108                 fn_len = vll;
13109                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13110                 CHECK_STRING_TRANS_SUBR(fn);
13111                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13112                         fn);
13113                 COUNT_BYTES_TRANS_SUBR(fn_len);
13114
13115                 break;
13116         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13117         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
13118                 /* create time */
13119                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13120                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13121                         hf_smb_create_time);
13122                 *bcp -= 8;
13123
13124                 /* volume serial number */
13125                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13126                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13127                 COUNT_BYTES_TRANS_SUBR(4);
13128
13129                 /* volume label length */
13130                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13131                 vll = tvb_get_letohl(tvb, offset);
13132                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13133                 COUNT_BYTES_TRANS_SUBR(4);
13134
13135                 /* 2 reserved bytes */
13136                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13137                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13138                 COUNT_BYTES_TRANS_SUBR(2);
13139
13140                 /* label */
13141                 fn_len = vll;
13142                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13143                 CHECK_STRING_TRANS_SUBR(fn);
13144                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13145                         fn);
13146                 COUNT_BYTES_TRANS_SUBR(fn_len);
13147
13148                 break;
13149         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13150         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13151                 /* allocation size */
13152                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13153                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13154                 COUNT_BYTES_TRANS_SUBR(8);
13155
13156                 /* free allocation units */
13157                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13158                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13159                 COUNT_BYTES_TRANS_SUBR(8);
13160
13161                 /* sectors per unit */
13162                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13163                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13164                 COUNT_BYTES_TRANS_SUBR(4);
13165
13166                 /* bytes per sector */
13167                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13168                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13169                 COUNT_BYTES_TRANS_SUBR(4);
13170
13171                 break;
13172         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13173         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13174                 /* device type */
13175                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13176                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13177                 COUNT_BYTES_TRANS_SUBR(4);
13178
13179                 /* device characteristics */
13180                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13181                 offset = dissect_device_characteristics(tvb, tree, offset);
13182                 *bcp -= 4;
13183
13184                 break;
13185         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13186         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13187                 /* FS attributes */
13188                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13189                 offset = dissect_fs_attributes(tvb, tree, offset);
13190                 *bcp -= 4;
13191
13192                 /* max name len */
13193                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13194                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13195                 COUNT_BYTES_TRANS_SUBR(4);
13196
13197                 /* fs name length */
13198                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13199                 fnl = tvb_get_letohl(tvb, offset);
13200                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13201                 COUNT_BYTES_TRANS_SUBR(4);
13202
13203                 /* label */
13204                 fn_len = fnl;
13205                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13206                 CHECK_STRING_TRANS_SUBR(fn);
13207                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13208                         fn);
13209                 COUNT_BYTES_TRANS_SUBR(fn_len);
13210
13211                 break;
13212         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13213                 proto_item *item = NULL;
13214                 proto_tree *subtree = NULL;
13215                 guint32 caps_lo, caps_hi;
13216
13217                 /* MajorVersionNumber */
13218                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13219                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13220                 COUNT_BYTES_TRANS_SUBR(2);
13221
13222                 /* MinorVersionNumber */
13223                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13224                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13225                 COUNT_BYTES_TRANS_SUBR(2);
13226
13227                 /* Capability */
13228
13229                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13230
13231                 caps_lo = tvb_get_letohl(tvb, offset);
13232                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13233
13234                 if (tree) {
13235                         item = proto_tree_add_text(
13236                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13237                                 caps_hi, caps_lo);
13238                         subtree = proto_item_add_subtree(
13239                                 item, ett_smb_unix_capabilities);
13240                 }
13241
13242                 proto_tree_add_boolean(
13243                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13244                         caps_lo);
13245
13246                 proto_tree_add_boolean(
13247                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13248                         caps_lo);
13249
13250                 COUNT_BYTES_TRANS_SUBR(8);
13251
13252                 break;
13253         }
13254         case 0x301:     /* MAC_QUERY_FS_INFO */
13255                 /* Create time */
13256                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13257                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13258                 *bcp -= 8;
13259                 /* Modify Time */
13260                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13261                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13262                 *bcp -= 8;
13263                 /* Backup Time */
13264                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13265                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13266                 *bcp -= 8;
13267                 /* Allocation blocks */
13268                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13269                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13270                                     offset,
13271                                     4, TRUE);
13272                 COUNT_BYTES_TRANS_SUBR(4);
13273                 /* Allocation Block Size */
13274                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13275                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13276                                     offset, 4, TRUE);
13277                 COUNT_BYTES_TRANS_SUBR(4);
13278                 /* Free Block Count */
13279                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13280                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13281                                     offset, 4, TRUE);
13282                 COUNT_BYTES_TRANS_SUBR(4);
13283                 /* Finder Info ... */
13284                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13285                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13286                                             offset, 32,
13287                                             tvb_get_ptr(tvb, offset,32),
13288                                             "Finder Info: %s",
13289                                             tvb_format_text(tvb, offset, 32));
13290                 COUNT_BYTES_TRANS_SUBR(32);
13291                 /* Number Files */
13292                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13293                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13294                                     offset, 4, TRUE);
13295                 COUNT_BYTES_TRANS_SUBR(4);
13296                 /* Number of Root Directories */
13297                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13298                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13299                                     offset, 4, TRUE);
13300                 COUNT_BYTES_TRANS_SUBR(4);
13301                 /* Number of files */
13302                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13303                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13304                                     offset, 4, TRUE);
13305                 COUNT_BYTES_TRANS_SUBR(4);
13306                 /* Dir Count */
13307                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13308                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13309                                     offset, 4, TRUE);
13310                 COUNT_BYTES_TRANS_SUBR(4);
13311                 /* Mac Support Flags */
13312                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13313                 support = tvb_get_ntohl(tvb, offset);
13314                 item = proto_tree_add_text(tree, tvb, offset, 4,
13315                                            "Mac Support Flags: 0x%08x", support);
13316                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13317                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13318                                        tvb, offset, 4, support);
13319                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13320                                        tvb, offset, 4, support);
13321                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13322                                        tvb, offset, 4, support);
13323                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13324                                        tvb, offset, 4, support);
13325                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13326                                        tvb, offset, 4, support);
13327                 COUNT_BYTES_TRANS_SUBR(4);
13328                 break;
13329         case 1006:      /* QUERY_FS_QUOTA_INFO */
13330                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13331                 break;
13332         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13333                 /* allocation size */
13334                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13335                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13336                 COUNT_BYTES_TRANS_SUBR(8);
13337
13338                 /* caller free allocation units */
13339                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13340                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13341                 COUNT_BYTES_TRANS_SUBR(8);
13342
13343                 /* actual free allocation units */
13344                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13345                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13346                 COUNT_BYTES_TRANS_SUBR(8);
13347
13348                 /* sectors per unit */
13349                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13350                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13351                 COUNT_BYTES_TRANS_SUBR(4);
13352
13353                 /* bytes per sector */
13354                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13355                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13356                 COUNT_BYTES_TRANS_SUBR(4);
13357                 break;
13358         case 1008: /* Query Object ID Information - unknown data */
13359                 /* XXX: TODO */
13360                 break;
13361         }
13362
13363         return offset;
13364 }
13365
13366 static int
13367 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13368     proto_tree *parent_tree)
13369 {
13370         proto_item *item = NULL;
13371         proto_tree *tree = NULL;
13372         smb_info_t *si;
13373         smb_transact2_info_t *t2i;
13374         int count;
13375         gboolean trunc;
13376         int offset = 0;
13377         guint16 dc;
13378
13379         dc = tvb_reported_length(tvb);
13380
13381         si = (smb_info_t *)pinfo->private_data;
13382         if (si->sip != NULL)
13383                 t2i = si->sip->extra_info;
13384         else
13385                 t2i = NULL;
13386
13387         if(parent_tree){
13388                 if (t2i != NULL && t2i->subcmd != -1) {
13389                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13390                                 "%s Data",
13391                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13392                                         "Unknown (0x%02x)"));
13393                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13394                 } else {
13395                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13396                                 "Unknown Transaction2 Data");
13397                 }
13398         }
13399
13400         if (t2i == NULL) {
13401                 offset += dc;
13402                 return offset;
13403         }
13404         switch(t2i->subcmd){
13405         case 0x00:      /*TRANS2_OPEN2*/
13406                 /* XXX not implemented yet. See SNIA doc */
13407                 break;
13408         case 0x01:      /*TRANS2_FIND_FIRST2*/
13409                 /* returned data */
13410                 count = si->info_count;
13411
13412                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13413                         col_append_fstr(pinfo->cinfo, COL_INFO,
13414                         ", Files:");
13415                 }
13416
13417                 while(count--){
13418                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13419                                 offset, &dc, &trunc);
13420                         if (trunc)
13421                                 break;
13422                 }
13423                 break;
13424         case 0x02:      /*TRANS2_FIND_NEXT2*/
13425                 /* returned data */
13426                 count = si->info_count;
13427
13428                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13429                         col_append_fstr(pinfo->cinfo, COL_INFO,
13430                         ", Files:");
13431                 }
13432
13433                 while(count--){
13434                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13435                                 offset, &dc, &trunc);
13436                         if (trunc)
13437                                 break;
13438                 }
13439                 break;
13440         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13441                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13442                 break;
13443         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13444                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13445                 break;
13446         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13447                 /* no data in this response */
13448                 break;
13449         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13450                 /* identical to QUERY_PATH_INFO */
13451                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13452                 break;
13453         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13454                 /* no data in this response */
13455                 break;
13456         case 0x09:      /*TRANS2_FSCTL*/
13457                 /* XXX dont know how to dissect this one (yet)*/
13458
13459                 /*
13460                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13461                  * Extensions Version 3.0, Document Version 1.11,
13462                  * July 19, 1990" says this this contains a
13463                  * "File system specific return data block".
13464                  * (That means we may not be able to dissect it in any
13465                  * case.)
13466                  */
13467                 break;
13468         case 0x0a:      /*TRANS2_IOCTL2*/
13469                 /* XXX dont know how to dissect this one (yet)*/
13470
13471                 /*
13472                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13473                  * Extensions Version 3.0, Document Version 1.11,
13474                  * July 19, 1990" says this this contains a
13475                  * "Device/function specific return data block".
13476                  * (That means we may not be able to dissect it in any
13477                  * case.)
13478                  */
13479                 break;
13480         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13481                 /* XXX dont know how to dissect this one (yet)*/
13482
13483                 /*
13484                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13485                  * Extensions Version 3.0, Document Version 1.11,
13486                  * July 19, 1990" says this this contains "the level
13487                  * dependent information about the changes which
13488                  * occurred".
13489                  */
13490                 break;
13491         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13492                 /* XXX dont know how to dissect this one (yet)*/
13493
13494                 /*
13495                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13496                  * Extensions Version 3.0, Document Version 1.11,
13497                  * July 19, 1990" says this this contains "the level
13498                  * dependent information about the changes which
13499                  * occurred".
13500                  */
13501                 break;
13502         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13503                 /* no data in this response */
13504                 break;
13505         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13506                 /* XXX dont know how to dissect this one (yet)*/
13507                 break;
13508         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13509                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13510                 break;
13511         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13512                 /* the SNIA spec appears to say the response has no data */
13513                 break;
13514         case -1:
13515                 /*
13516                  * We don't know what the matching request was; don't
13517                  * bother putting anything else into the tree for the data.
13518                  */
13519                 offset += dc;
13520                 dc = 0;
13521                 break;
13522         }
13523
13524         /* ooops there were data we didnt know how to process */
13525         if(dc != 0){
13526                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13527                 offset += dc;
13528         }
13529
13530         return offset;
13531 }
13532
13533
13534 static void
13535 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13536 {
13537         proto_item *item = NULL;
13538         proto_tree *tree = NULL;
13539         smb_info_t *si;
13540         smb_transact2_info_t *t2i;
13541         guint16 fid;
13542         int lno;
13543         int offset = 0;
13544         int pc;
13545
13546         pc = tvb_reported_length(tvb);
13547
13548         si = (smb_info_t *)pinfo->private_data;
13549         if (si->sip != NULL)
13550                 t2i = si->sip->extra_info;
13551         else
13552                 t2i = NULL;
13553
13554         if(parent_tree){
13555                 if (t2i != NULL && t2i->subcmd != -1) {
13556                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13557                                 "%s Parameters",
13558                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13559                                                 "Unknown (0x%02x)"));
13560                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13561                 } else {
13562                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13563                                 "Unknown Transaction2 Parameters");
13564                 }
13565         }
13566
13567         if (t2i == NULL) {
13568                 offset += pc;
13569                 return;
13570         }
13571         switch(t2i->subcmd){
13572         case 0x00:      /*TRANS2_OPEN2*/
13573                 /* fid */
13574                 fid = tvb_get_letohs(tvb, offset);
13575                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13576                 offset += 2;
13577
13578                 /*
13579                  * XXX - Microsoft Networks SMB File Sharing Protocol
13580                  * Extensions Version 3.0, Document Version 1.11,
13581                  * July 19, 1990 says that the file attributes, create
13582                  * time (which it says is the last modification time),
13583                  * data size, granted access, file type, and IPC state
13584                  * are returned only if bit 0 is set in the open flags,
13585                  * and that the EA length is returned only if bit 3
13586                  * is set in the open flags.  Does that mean that,
13587                  * at least in that SMB dialect, those fields are not
13588                  * present in the reply parameters if the bits in
13589                  * question aren't set?
13590                  */
13591
13592                 /* File Attributes */
13593                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13594
13595                 /* create time */
13596                 offset = dissect_smb_datetime(tvb, tree, offset,
13597                         hf_smb_create_time,
13598                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13599
13600                 /* data size */
13601                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13602                 offset += 4;
13603
13604                 /* granted access */
13605                 offset = dissect_access(tvb, tree, offset, "Granted");
13606
13607                 /* File Type */
13608                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13609                 offset += 2;
13610
13611                 /* IPC State */
13612                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13613
13614                 /* open_action */
13615                 offset = dissect_open_action(tvb, tree, offset);
13616
13617                 /* server unique file ID */
13618                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13619                 offset += 4;
13620
13621                 /* ea error offset, only a 16 bit integer here */
13622                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13623                 offset += 2;
13624
13625                 /* ea length */
13626                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13627                 offset += 4;
13628
13629                 break;
13630         case 0x01:      /*TRANS2_FIND_FIRST2*/
13631                 /* Find First2 information level */
13632                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13633
13634                 /* sid */
13635                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13636                 offset += 2;
13637
13638                 /* search count */
13639                 si->info_count = tvb_get_letohs(tvb, offset);
13640                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13641                 offset += 2;
13642
13643                 /* end of search */
13644                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13645                 offset += 2;
13646
13647                 /* ea error offset, only a 16 bit integer here */
13648                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13649                 offset += 2;
13650
13651                 /* last name offset */
13652                 lno = tvb_get_letohs(tvb, offset);
13653                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13654                 offset += 2;
13655
13656                 break;
13657         case 0x02:      /*TRANS2_FIND_NEXT2*/
13658                 /* search count */
13659                 si->info_count = tvb_get_letohs(tvb, offset);
13660                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13661                 offset += 2;
13662
13663                 /* end of search */
13664                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13665                 offset += 2;
13666
13667                 /* ea_error_offset, only a 16 bit integer here*/
13668                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13669                 offset += 2;
13670
13671                 /* last name offset */
13672                 lno = tvb_get_letohs(tvb, offset);
13673                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13674                 offset += 2;
13675
13676                 break;
13677         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13678                 /* no parameter block here */
13679                 break;
13680         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13681                 /* ea_error_offset, only a 16 bit integer here*/
13682                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13683                 offset += 2;
13684
13685                 break;
13686         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13687                 /* ea_error_offset, only a 16 bit integer here*/
13688                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13689                 offset += 2;
13690
13691                 break;
13692         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13693                 /* ea_error_offset, only a 16 bit integer here*/
13694                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13695                 offset += 2;
13696
13697                 break;
13698         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13699                 /* ea_error_offset, only a 16 bit integer here*/
13700                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13701                 offset += 2;
13702
13703                 break;
13704         case 0x09:      /*TRANS2_FSCTL*/
13705                 /* XXX dont know how to dissect this one (yet)*/
13706
13707                 /*
13708                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13709                  * Extensions Version 3.0, Document Version 1.11,
13710                  * July 19, 1990" says this this contains a
13711                  * "File system specific return parameter block".
13712                  * (That means we may not be able to dissect it in any
13713                  * case.)
13714                  */
13715                 break;
13716         case 0x0a:      /*TRANS2_IOCTL2*/
13717                 /* XXX dont know how to dissect this one (yet)*/
13718
13719                 /*
13720                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13721                  * Extensions Version 3.0, Document Version 1.11,
13722                  * July 19, 1990" says this this contains a
13723                  * "Device/function specific return parameter block".
13724                  * (That means we may not be able to dissect it in any
13725                  * case.)
13726                  */
13727                 break;
13728         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13729                 /* Find Notify information level */
13730                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13731
13732                 /* Monitor handle */
13733                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13734                 offset += 2;
13735
13736                 /* Change count */
13737                 si->info_count = tvb_get_letohs(tvb, offset);
13738                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13739                 offset += 2;
13740
13741                 /* ea_error_offset, only a 16 bit integer here*/
13742                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13743                 offset += 2;
13744
13745                 break;
13746         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13747                 /* Find Notify information level */
13748                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13749
13750                 /* Change count */
13751                 si->info_count = tvb_get_letohs(tvb, offset);
13752                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13753                 offset += 2;
13754
13755                 /* ea_error_offset, only a 16 bit integer here*/
13756                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13757                 offset += 2;
13758
13759                 break;
13760         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13761                 /* ea error offset, only a 16 bit integer here */
13762                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13763                 offset += 2;
13764
13765                 break;
13766         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13767                 /* XXX dont know how to dissect this one (yet)*/
13768                 break;
13769         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13770                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13771                 break;
13772         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13773                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13774                 break;
13775         case -1:
13776                 /*
13777                  * We don't know what the matching request was; don't
13778                  * bother putting anything else into the tree for the data.
13779                  */
13780                 offset += pc;
13781                 break;
13782         }
13783
13784         /* ooops there were data we didnt know how to process */
13785         if(offset<pc){
13786                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13787                 offset += pc-offset;
13788         }
13789 }
13790
13791
13792 static int
13793 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13794 {
13795         guint8 sc, wc;
13796         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13797         smb_info_t *si;
13798         smb_transact2_info_t *t2i = NULL;
13799         guint16 bc;
13800         int padcnt;
13801         gboolean dissected_trans;
13802         fragment_data *r_fd = NULL;
13803         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13804         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13805         gboolean save_fragmented;
13806
13807         si = (smb_info_t *)pinfo->private_data;
13808
13809         switch(si->cmd){
13810         case SMB_COM_TRANSACTION2:
13811                 /* transaction2 */
13812                 if (si->sip != NULL) {
13813                         t2i = si->sip->extra_info;
13814                 } else
13815                         t2i = NULL;
13816                 if (t2i == NULL) {
13817                         /*
13818                          * We didn't see the matching request, so we don't
13819                          * know what type of transaction this is.
13820                          */
13821                         proto_tree_add_text(tree, tvb, 0, 0,
13822                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13823                         if (check_col(pinfo->cinfo, COL_INFO)) {
13824                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13825                         }
13826                 } else {
13827                         si->info_level = t2i->info_level;
13828                         if (t2i->subcmd == -1) {
13829                                 /*
13830                                  * We didn't manage to extract the subcommand
13831                                  * from the matching request (perhaps because
13832                                  * the frame was short), so we don't know what
13833                                  * type of transaction this is.
13834                                  */
13835                                 proto_tree_add_text(tree, tvb, 0, 0,
13836                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13837                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13838                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13839                                 }
13840                         } else {
13841                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13842                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13843                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13844                                                 val_to_str(t2i->subcmd,
13845                                                         trans2_cmd_vals,
13846                                                         "<unknown (0x%02x)>"));
13847                                 }
13848                         }
13849                 }
13850                 break;
13851         }
13852
13853         WORD_COUNT;
13854
13855         /* total param count, only a 16bit integer here */
13856         tp = tvb_get_letohs(tvb, offset);
13857         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
13858         offset += 2;
13859
13860         /* total data count, only a 16 bit integer here */
13861         td = tvb_get_letohs(tvb, offset);
13862         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
13863         offset += 2;
13864
13865         /* 2 reserved bytes */
13866         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13867         offset += 2;
13868
13869         /* param count */
13870         pc = tvb_get_letohs(tvb, offset);
13871         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13872         offset += 2;
13873
13874         /* param offset */
13875         po = tvb_get_letohs(tvb, offset);
13876         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13877         offset += 2;
13878
13879         /* param disp */
13880         pd = tvb_get_letohs(tvb, offset);
13881         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13882         offset += 2;
13883
13884         /* data count */
13885         dc = tvb_get_letohs(tvb, offset);
13886         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13887         offset += 2;
13888
13889         /* data offset */
13890         od = tvb_get_letohs(tvb, offset);
13891         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13892         offset += 2;
13893
13894         /* data disp */
13895         dd = tvb_get_letohs(tvb, offset);
13896         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13897         offset += 2;
13898
13899         /* setup count */
13900         sc = tvb_get_guint8(tvb, offset);
13901         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13902         offset += 1;
13903
13904         /* reserved byte */
13905         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13906         offset += 1;
13907
13908
13909         /* if there were any setup bytes, put them in a tvb for later */
13910         if(sc){
13911                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13912                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13913                 } else {
13914                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13915                 }
13916                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13917         } else {
13918                 s_tvb = NULL;
13919                 sp_tvb=NULL;
13920         }
13921         offset += 2*sc;
13922
13923
13924         BYTE_COUNT;
13925
13926
13927         /* reassembly of SMB Transaction data payload.
13928            In this section we do reassembly of both the data and parameters
13929            blocks of the SMB transaction command.
13930         */
13931         save_fragmented = pinfo->fragmented;
13932         /* do we need reassembly? */
13933         if( (td!=dc) || (tp!=pc) ){
13934                 /* oh yeah, either data or parameter section needs
13935                    reassembly
13936                 */
13937                 pinfo->fragmented = TRUE;
13938                 if(smb_trans_reassembly){
13939                         /* ...and we were told to do reassembly */
13940                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13941                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13942                                                              po, pc, pd, td+tp);
13943
13944                         }
13945                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13946                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13947                                                              od, dc, dd+tp, td+tp);
13948                         }
13949                 }
13950         }
13951
13952         /* if we got a reassembled fd structure from the reassembly routine we must
13953            create pd_tvb from it
13954         */
13955         if(r_fd){
13956                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13957                                              r_fd->datalen);
13958                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13959                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13960                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13961         }
13962
13963
13964         if(pd_tvb){
13965                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13966                 if(tp){
13967                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13968                 }
13969                 if(td){
13970                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13971                 }
13972         } else {
13973                 /* It was not reassembled. Do as best as we can.
13974                  * in this case we always try to dissect the stuff if
13975                  * data and param displacement is 0. i.e. for the first
13976                  * (and maybe only) packet.
13977                  */
13978                 if( (pd==0) && (dd==0) ){
13979                         int min;
13980                         int reported_min;
13981                         min = MIN(pc,tvb_length_remaining(tvb,po));
13982                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13983                         if(min && reported_min) {
13984                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13985                         }
13986                         min = MIN(dc,tvb_length_remaining(tvb,od));
13987                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13988                         if(min && reported_min) {
13989                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13990                         }
13991                         /*
13992                          * A tvbuff containing the parameters
13993                          * and the data.
13994                          * XXX - check pc and dc as well?
13995                          */
13996                         if (tvb_length_remaining(tvb, po)){
13997                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13998                         }
13999                 }
14000         }
14001
14002
14003
14004         /* parameters */
14005         if(po>offset){
14006                 /* We have some padding bytes.
14007                 */
14008                 padcnt = po-offset;
14009                 if (padcnt > bc)
14010                         padcnt = bc;
14011                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14012                 COUNT_BYTES(padcnt);
14013         }
14014         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14015                 /* TRANSACTION2 parameters*/
14016                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14017         }
14018         COUNT_BYTES(pc);
14019
14020
14021         /* data */
14022         if(od>offset){
14023                 /* We have some initial padding bytes.
14024                 */
14025                 padcnt = od-offset;
14026                 if (padcnt > bc)
14027                         padcnt = bc;
14028                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14029                 COUNT_BYTES(padcnt);
14030         }
14031         /*
14032          * If the data count is bigger than the count of bytes
14033          * remaining, clamp it so that the count of bytes remaining
14034          * doesn't go negative.
14035          */
14036         if (dc > bc)
14037                 dc = bc;
14038         COUNT_BYTES(dc);
14039
14040
14041
14042         /* from now on, everything is in separate tvbuffs so we dont count
14043            the bytes with COUNT_BYTES any more.
14044            neither do we reference offset any more (which by now points to the
14045            first byte AFTER this PDU */
14046
14047
14048         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14049                 /* TRANSACTION2 parameters*/
14050                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14051         }
14052
14053
14054         if(si->cmd==SMB_COM_TRANSACTION){
14055                 smb_transact_info_t *tri;
14056
14057                 dissected_trans = FALSE;
14058                 if (si->sip != NULL)
14059                         tri = si->sip->extra_info;
14060                 else
14061                         tri = NULL;
14062                 if (tri != NULL) {
14063                         switch(tri->subcmd){
14064
14065                         case TRANSACTION_PIPE:
14066                                 /* This function is safe to call for
14067                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14068                                    know them at this point.
14069                                    It's also safe to call if "p_tvb"
14070                                    or "d_tvb" are null.
14071                                 */
14072                                 if( pd_tvb) {
14073                                         dissected_trans = dissect_pipe_smb(
14074                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14075                                                 d_tvb, NULL, pinfo, top_tree);
14076                                 }
14077                                 break;
14078
14079                         case TRANSACTION_MAILSLOT:
14080                                 /* This one should be safe to call
14081                                    even if s_tvb and sp_tvb is NULL
14082                                 */
14083                                 if(d_tvb){
14084                                         dissected_trans = dissect_mailslot_smb(
14085                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14086                                                 top_tree);
14087                                 }
14088                                 break;
14089                         }
14090                 }
14091                 if (!dissected_trans) {
14092                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14093                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14094                 }
14095         }
14096
14097
14098         if( (p_tvb==0) && (d_tvb==0) ){
14099                 if(check_col(pinfo->cinfo, COL_INFO)){
14100                         col_append_str(pinfo->cinfo, COL_INFO,
14101                                        "[transact continuation]");
14102                 }
14103         }
14104
14105         pinfo->fragmented = save_fragmented;
14106         END_OF_SMB
14107
14108         return offset;
14109 }
14110
14111
14112 static int
14113 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14114 {
14115         guint8 wc;
14116         guint16 bc;
14117
14118         WORD_COUNT;
14119
14120         /* Monitor handle */
14121         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14122         offset += 2;
14123
14124         BYTE_COUNT;
14125
14126         END_OF_SMB
14127
14128         return offset;
14129 }
14130
14131 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14132    END Transaction/Transaction2 Primary and secondary requests
14133    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14134
14135
14136 static int
14137 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14138 {
14139         guint8 wc;
14140         guint16 bc;
14141
14142         WORD_COUNT;
14143
14144         if (wc != 0) {
14145                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14146                 offset += wc*2;
14147         }
14148
14149         BYTE_COUNT;
14150
14151         if (bc != 0) {
14152                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14153                 offset += bc;
14154                 bc = 0;
14155         }
14156
14157         END_OF_SMB
14158
14159         return offset;
14160 }
14161
14162 typedef struct _smb_function {
14163        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14164        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14165 } smb_function;
14166
14167 static smb_function smb_dissector[256] = {
14168   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14169   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14170   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14171   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14172   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14173   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14174   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14175   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14176   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14177   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14178   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14179   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14180   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14181   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14182   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14183   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14184
14185   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14186   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14187   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14188   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14189   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14190   /* 0x15 */  {dissect_unknown, dissect_unknown},
14191   /* 0x16 */  {dissect_unknown, dissect_unknown},
14192   /* 0x17 */  {dissect_unknown, dissect_unknown},
14193   /* 0x18 */  {dissect_unknown, dissect_unknown},
14194   /* 0x19 */  {dissect_unknown, dissect_unknown},
14195   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14196   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14197   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14198   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14199   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14200   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14201
14202   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14203   /* 0x21 */  {dissect_unknown, dissect_unknown},
14204   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14205   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14206   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14207   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14208   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14209   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14210   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14211   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14212   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14213   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14214   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14215   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14216   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14217   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14218
14219   /* 0x30 */  {dissect_unknown, dissect_unknown},
14220   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14221   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14222   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14223   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14224   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14225   /* 0x36 */  {dissect_unknown, dissect_unknown},
14226   /* 0x37 */  {dissect_unknown, dissect_unknown},
14227   /* 0x38 */  {dissect_unknown, dissect_unknown},
14228   /* 0x39 */  {dissect_unknown, dissect_unknown},
14229   /* 0x3a */  {dissect_unknown, dissect_unknown},
14230   /* 0x3b */  {dissect_unknown, dissect_unknown},
14231   /* 0x3c */  {dissect_unknown, dissect_unknown},
14232   /* 0x3d */  {dissect_unknown, dissect_unknown},
14233   /* 0x3e */  {dissect_unknown, dissect_unknown},
14234   /* 0x3f */  {dissect_unknown, dissect_unknown},
14235
14236   /* 0x40 */  {dissect_unknown, dissect_unknown},
14237   /* 0x41 */  {dissect_unknown, dissect_unknown},
14238   /* 0x42 */  {dissect_unknown, dissect_unknown},
14239   /* 0x43 */  {dissect_unknown, dissect_unknown},
14240   /* 0x44 */  {dissect_unknown, dissect_unknown},
14241   /* 0x45 */  {dissect_unknown, dissect_unknown},
14242   /* 0x46 */  {dissect_unknown, dissect_unknown},
14243   /* 0x47 */  {dissect_unknown, dissect_unknown},
14244   /* 0x48 */  {dissect_unknown, dissect_unknown},
14245   /* 0x49 */  {dissect_unknown, dissect_unknown},
14246   /* 0x4a */  {dissect_unknown, dissect_unknown},
14247   /* 0x4b */  {dissect_unknown, dissect_unknown},
14248   /* 0x4c */  {dissect_unknown, dissect_unknown},
14249   /* 0x4d */  {dissect_unknown, dissect_unknown},
14250   /* 0x4e */  {dissect_unknown, dissect_unknown},
14251   /* 0x4f */  {dissect_unknown, dissect_unknown},
14252
14253   /* 0x50 */  {dissect_unknown, dissect_unknown},
14254   /* 0x51 */  {dissect_unknown, dissect_unknown},
14255   /* 0x52 */  {dissect_unknown, dissect_unknown},
14256   /* 0x53 */  {dissect_unknown, dissect_unknown},
14257   /* 0x54 */  {dissect_unknown, dissect_unknown},
14258   /* 0x55 */  {dissect_unknown, dissect_unknown},
14259   /* 0x56 */  {dissect_unknown, dissect_unknown},
14260   /* 0x57 */  {dissect_unknown, dissect_unknown},
14261   /* 0x58 */  {dissect_unknown, dissect_unknown},
14262   /* 0x59 */  {dissect_unknown, dissect_unknown},
14263   /* 0x5a */  {dissect_unknown, dissect_unknown},
14264   /* 0x5b */  {dissect_unknown, dissect_unknown},
14265   /* 0x5c */  {dissect_unknown, dissect_unknown},
14266   /* 0x5d */  {dissect_unknown, dissect_unknown},
14267   /* 0x5e */  {dissect_unknown, dissect_unknown},
14268   /* 0x5f */  {dissect_unknown, dissect_unknown},
14269
14270   /* 0x60 */  {dissect_unknown, dissect_unknown},
14271   /* 0x61 */  {dissect_unknown, dissect_unknown},
14272   /* 0x62 */  {dissect_unknown, dissect_unknown},
14273   /* 0x63 */  {dissect_unknown, dissect_unknown},
14274   /* 0x64 */  {dissect_unknown, dissect_unknown},
14275   /* 0x65 */  {dissect_unknown, dissect_unknown},
14276   /* 0x66 */  {dissect_unknown, dissect_unknown},
14277   /* 0x67 */  {dissect_unknown, dissect_unknown},
14278   /* 0x68 */  {dissect_unknown, dissect_unknown},
14279   /* 0x69 */  {dissect_unknown, dissect_unknown},
14280   /* 0x6a */  {dissect_unknown, dissect_unknown},
14281   /* 0x6b */  {dissect_unknown, dissect_unknown},
14282   /* 0x6c */  {dissect_unknown, dissect_unknown},
14283   /* 0x6d */  {dissect_unknown, dissect_unknown},
14284   /* 0x6e */  {dissect_unknown, dissect_unknown},
14285   /* 0x6f */  {dissect_unknown, dissect_unknown},
14286
14287   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14288   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14289   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14290   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14291   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14292   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14293   /* 0x76 */  {dissect_unknown, dissect_unknown},
14294   /* 0x77 */  {dissect_unknown, dissect_unknown},
14295   /* 0x78 */  {dissect_unknown, dissect_unknown},
14296   /* 0x79 */  {dissect_unknown, dissect_unknown},
14297   /* 0x7a */  {dissect_unknown, dissect_unknown},
14298   /* 0x7b */  {dissect_unknown, dissect_unknown},
14299   /* 0x7c */  {dissect_unknown, dissect_unknown},
14300   /* 0x7d */  {dissect_unknown, dissect_unknown},
14301   /* 0x7e */  {dissect_unknown, dissect_unknown},
14302   /* 0x7f */  {dissect_unknown, dissect_unknown},
14303
14304   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14305   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14306   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14307   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14308   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14309   /* 0x85 */  {dissect_unknown, dissect_unknown},
14310   /* 0x86 */  {dissect_unknown, dissect_unknown},
14311   /* 0x87 */  {dissect_unknown, dissect_unknown},
14312   /* 0x88 */  {dissect_unknown, dissect_unknown},
14313   /* 0x89 */  {dissect_unknown, dissect_unknown},
14314   /* 0x8a */  {dissect_unknown, dissect_unknown},
14315   /* 0x8b */  {dissect_unknown, dissect_unknown},
14316   /* 0x8c */  {dissect_unknown, dissect_unknown},
14317   /* 0x8d */  {dissect_unknown, dissect_unknown},
14318   /* 0x8e */  {dissect_unknown, dissect_unknown},
14319   /* 0x8f */  {dissect_unknown, dissect_unknown},
14320
14321   /* 0x90 */  {dissect_unknown, dissect_unknown},
14322   /* 0x91 */  {dissect_unknown, dissect_unknown},
14323   /* 0x92 */  {dissect_unknown, dissect_unknown},
14324   /* 0x93 */  {dissect_unknown, dissect_unknown},
14325   /* 0x94 */  {dissect_unknown, dissect_unknown},
14326   /* 0x95 */  {dissect_unknown, dissect_unknown},
14327   /* 0x96 */  {dissect_unknown, dissect_unknown},
14328   /* 0x97 */  {dissect_unknown, dissect_unknown},
14329   /* 0x98 */  {dissect_unknown, dissect_unknown},
14330   /* 0x99 */  {dissect_unknown, dissect_unknown},
14331   /* 0x9a */  {dissect_unknown, dissect_unknown},
14332   /* 0x9b */  {dissect_unknown, dissect_unknown},
14333   /* 0x9c */  {dissect_unknown, dissect_unknown},
14334   /* 0x9d */  {dissect_unknown, dissect_unknown},
14335   /* 0x9e */  {dissect_unknown, dissect_unknown},
14336   /* 0x9f */  {dissect_unknown, dissect_unknown},
14337
14338   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14339   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14340   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14341   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14342   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14343   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14344   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14345   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14346   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14347   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14348   /* 0xaa */  {dissect_unknown, dissect_unknown},
14349   /* 0xab */  {dissect_unknown, dissect_unknown},
14350   /* 0xac */  {dissect_unknown, dissect_unknown},
14351   /* 0xad */  {dissect_unknown, dissect_unknown},
14352   /* 0xae */  {dissect_unknown, dissect_unknown},
14353   /* 0xaf */  {dissect_unknown, dissect_unknown},
14354
14355   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14356   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14357   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14358   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14359   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14360   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14361   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14362   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14363   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14364   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14365   /* 0xba */  {dissect_unknown, dissect_unknown},
14366   /* 0xbb */  {dissect_unknown, dissect_unknown},
14367   /* 0xbc */  {dissect_unknown, dissect_unknown},
14368   /* 0xbd */  {dissect_unknown, dissect_unknown},
14369   /* 0xbe */  {dissect_unknown, dissect_unknown},
14370   /* 0xbf */  {dissect_unknown, dissect_unknown},
14371
14372   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14373   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14374   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14375   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14376   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14377   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14378   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14379   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14380   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14381   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14382   /* 0xca */  {dissect_unknown, dissect_unknown},
14383   /* 0xcb */  {dissect_unknown, dissect_unknown},
14384   /* 0xcc */  {dissect_unknown, dissect_unknown},
14385   /* 0xcd */  {dissect_unknown, dissect_unknown},
14386   /* 0xce */  {dissect_unknown, dissect_unknown},
14387   /* 0xcf */  {dissect_unknown, dissect_unknown},
14388
14389   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14390   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14391   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14392   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14393   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14394   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14395   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14396   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14397   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14398   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14399   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14400   /* 0xdb */  {dissect_unknown, dissect_unknown},
14401   /* 0xdc */  {dissect_unknown, dissect_unknown},
14402   /* 0xdd */  {dissect_unknown, dissect_unknown},
14403   /* 0xde */  {dissect_unknown, dissect_unknown},
14404   /* 0xdf */  {dissect_unknown, dissect_unknown},
14405
14406   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14407   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14408   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14409   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14410   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14411   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14412   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14413   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14414   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14415   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14416   /* 0xea */  {dissect_unknown, dissect_unknown},
14417   /* 0xeb */  {dissect_unknown, dissect_unknown},
14418   /* 0xec */  {dissect_unknown, dissect_unknown},
14419   /* 0xed */  {dissect_unknown, dissect_unknown},
14420   /* 0xee */  {dissect_unknown, dissect_unknown},
14421   /* 0xef */  {dissect_unknown, dissect_unknown},
14422
14423   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14424   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14425   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14426   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14427   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14428   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14429   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14430   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14431   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14432   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14433   /* 0xfa */  {dissect_unknown, dissect_unknown},
14434   /* 0xfb */  {dissect_unknown, dissect_unknown},
14435   /* 0xfc */  {dissect_unknown, dissect_unknown},
14436   /* 0xfd */  {dissect_unknown, dissect_unknown},
14437   /* 0xfe */  {dissect_unknown, dissect_unknown},
14438   /* 0xff */  {dissect_unknown, dissect_unknown},
14439 };
14440
14441 static int
14442 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14443 {
14444         smb_info_t *si;
14445
14446         si = pinfo->private_data;
14447         if(cmd!=0xff){
14448                 proto_item *cmd_item;
14449                 proto_tree *cmd_tree;
14450                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14451
14452                 if (check_col(pinfo->cinfo, COL_INFO)) {
14453                         if(first_pdu){
14454                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14455                                         "%s %s",
14456                                         decode_smb_name(cmd),
14457                                         (si->request)? "Request" : "Response");
14458                         } else {
14459                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14460                                         "; %s",
14461                                         decode_smb_name(cmd));
14462                         }
14463
14464                 }
14465
14466                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14467                         "%s %s (0x%02x)",
14468                         decode_smb_name(cmd),
14469                         (si->request)?"Request":"Response",
14470                         cmd);
14471
14472                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14473
14474                 dissector = (si->request)?
14475                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14476
14477                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14478                 proto_item_set_end(cmd_item, tvb, offset);
14479         }
14480         return offset;
14481 }
14482
14483
14484 /* NOTE: this value_string array will also be used to access data directly by
14485  * index instead of val_to_str() since
14486  * 1, the array will always span every value from 0x00 to 0xff and
14487  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14488  * This means that this value_string array MUST always
14489  * 1, contain all entries 0x00 to 0xff
14490  * 2, all entries must be in order.
14491  */
14492 const value_string smb_cmd_vals[] = {
14493   { 0x00, "Create Directory" },
14494   { 0x01, "Delete Directory" },
14495   { 0x02, "Open" },
14496   { 0x03, "Create" },
14497   { 0x04, "Close" },
14498   { 0x05, "Flush" },
14499   { 0x06, "Delete" },
14500   { 0x07, "Rename" },
14501   { 0x08, "Query Information" },
14502   { 0x09, "Set Information" },
14503   { 0x0A, "Read" },
14504   { 0x0B, "Write" },
14505   { 0x0C, "Lock Byte Range" },
14506   { 0x0D, "Unlock Byte Range" },
14507   { 0x0E, "Create Temp" },
14508   { 0x0F, "Create New" },
14509   { 0x10, "Check Directory" },
14510   { 0x11, "Process Exit" },
14511   { 0x12, "Seek" },
14512   { 0x13, "Lock And Read" },
14513   { 0x14, "Write And Unlock" },
14514   { 0x15, "unknown-0x15" },
14515   { 0x16, "unknown-0x16" },
14516   { 0x17, "unknown-0x17" },
14517   { 0x18, "unknown-0x18" },
14518   { 0x19, "unknown-0x19" },
14519   { 0x1A, "Read Raw" },
14520   { 0x1B, "Read MPX" },
14521   { 0x1C, "Read MPX Secondary" },
14522   { 0x1D, "Write Raw" },
14523   { 0x1E, "Write MPX" },
14524   { 0x1F, "Write MPX Secondary" },
14525   { 0x20, "Write Complete" },
14526   { 0x21, "unknown-0x21" },
14527   { 0x22, "Set Information2" },
14528   { 0x23, "Query Information2" },
14529   { 0x24, "Locking AndX" },
14530   { 0x25, "Transaction" },
14531   { 0x26, "Transaction Secondary" },
14532   { 0x27, "IOCTL" },
14533   { 0x28, "IOCTL Secondary" },
14534   { 0x29, "Copy" },
14535   { 0x2A, "Move" },
14536   { 0x2B, "Echo" },
14537   { 0x2C, "Write And Close" },
14538   { 0x2D, "Open AndX" },
14539   { 0x2E, "Read AndX" },
14540   { 0x2F, "Write AndX" },
14541   { 0x30, "unknown-0x30" },
14542   { 0x31, "Close And Tree Disconnect" },
14543   { 0x32, "Transaction2" },
14544   { 0x33, "Transaction2 Secondary" },
14545   { 0x34, "Find Close2" },
14546   { 0x35, "Find Notify Close" },
14547   { 0x36, "unknown-0x36" },
14548   { 0x37, "unknown-0x37" },
14549   { 0x38, "unknown-0x38" },
14550   { 0x39, "unknown-0x39" },
14551   { 0x3A, "unknown-0x3A" },
14552   { 0x3B, "unknown-0x3B" },
14553   { 0x3C, "unknown-0x3C" },
14554   { 0x3D, "unknown-0x3D" },
14555   { 0x3E, "unknown-0x3E" },
14556   { 0x3F, "unknown-0x3F" },
14557   { 0x40, "unknown-0x40" },
14558   { 0x41, "unknown-0x41" },
14559   { 0x42, "unknown-0x42" },
14560   { 0x43, "unknown-0x43" },
14561   { 0x44, "unknown-0x44" },
14562   { 0x45, "unknown-0x45" },
14563   { 0x46, "unknown-0x46" },
14564   { 0x47, "unknown-0x47" },
14565   { 0x48, "unknown-0x48" },
14566   { 0x49, "unknown-0x49" },
14567   { 0x4A, "unknown-0x4A" },
14568   { 0x4B, "unknown-0x4B" },
14569   { 0x4C, "unknown-0x4C" },
14570   { 0x4D, "unknown-0x4D" },
14571   { 0x4E, "unknown-0x4E" },
14572   { 0x4F, "unknown-0x4F" },
14573   { 0x50, "unknown-0x50" },
14574   { 0x51, "unknown-0x51" },
14575   { 0x52, "unknown-0x52" },
14576   { 0x53, "unknown-0x53" },
14577   { 0x54, "unknown-0x54" },
14578   { 0x55, "unknown-0x55" },
14579   { 0x56, "unknown-0x56" },
14580   { 0x57, "unknown-0x57" },
14581   { 0x58, "unknown-0x58" },
14582   { 0x59, "unknown-0x59" },
14583   { 0x5A, "unknown-0x5A" },
14584   { 0x5B, "unknown-0x5B" },
14585   { 0x5C, "unknown-0x5C" },
14586   { 0x5D, "unknown-0x5D" },
14587   { 0x5E, "unknown-0x5E" },
14588   { 0x5F, "unknown-0x5F" },
14589   { 0x60, "unknown-0x60" },
14590   { 0x61, "unknown-0x61" },
14591   { 0x62, "unknown-0x62" },
14592   { 0x63, "unknown-0x63" },
14593   { 0x64, "unknown-0x64" },
14594   { 0x65, "unknown-0x65" },
14595   { 0x66, "unknown-0x66" },
14596   { 0x67, "unknown-0x67" },
14597   { 0x68, "unknown-0x68" },
14598   { 0x69, "unknown-0x69" },
14599   { 0x6A, "unknown-0x6A" },
14600   { 0x6B, "unknown-0x6B" },
14601   { 0x6C, "unknown-0x6C" },
14602   { 0x6D, "unknown-0x6D" },
14603   { 0x6E, "unknown-0x6E" },
14604   { 0x6F, "unknown-0x6F" },
14605   { 0x70, "Tree Connect" },
14606   { 0x71, "Tree Disconnect" },
14607   { 0x72, "Negotiate Protocol" },
14608   { 0x73, "Session Setup AndX" },
14609   { 0x74, "Logoff AndX" },
14610   { 0x75, "Tree Connect AndX" },
14611   { 0x76, "unknown-0x76" },
14612   { 0x77, "unknown-0x77" },
14613   { 0x78, "unknown-0x78" },
14614   { 0x79, "unknown-0x79" },
14615   { 0x7A, "unknown-0x7A" },
14616   { 0x7B, "unknown-0x7B" },
14617   { 0x7C, "unknown-0x7C" },
14618   { 0x7D, "unknown-0x7D" },
14619   { 0x7E, "unknown-0x7E" },
14620   { 0x7F, "unknown-0x7F" },
14621   { 0x80, "Query Information Disk" },
14622   { 0x81, "Search" },
14623   { 0x82, "Find" },
14624   { 0x83, "Find Unique" },
14625   { 0x84, "Find Close" },
14626   { 0x85, "unknown-0x85" },
14627   { 0x86, "unknown-0x86" },
14628   { 0x87, "unknown-0x87" },
14629   { 0x88, "unknown-0x88" },
14630   { 0x89, "unknown-0x89" },
14631   { 0x8A, "unknown-0x8A" },
14632   { 0x8B, "unknown-0x8B" },
14633   { 0x8C, "unknown-0x8C" },
14634   { 0x8D, "unknown-0x8D" },
14635   { 0x8E, "unknown-0x8E" },
14636   { 0x8F, "unknown-0x8F" },
14637   { 0x90, "unknown-0x90" },
14638   { 0x91, "unknown-0x91" },
14639   { 0x92, "unknown-0x92" },
14640   { 0x93, "unknown-0x93" },
14641   { 0x94, "unknown-0x94" },
14642   { 0x95, "unknown-0x95" },
14643   { 0x96, "unknown-0x96" },
14644   { 0x97, "unknown-0x97" },
14645   { 0x98, "unknown-0x98" },
14646   { 0x99, "unknown-0x99" },
14647   { 0x9A, "unknown-0x9A" },
14648   { 0x9B, "unknown-0x9B" },
14649   { 0x9C, "unknown-0x9C" },
14650   { 0x9D, "unknown-0x9D" },
14651   { 0x9E, "unknown-0x9E" },
14652   { 0x9F, "unknown-0x9F" },
14653   { 0xA0, "NT Transact" },
14654   { 0xA1, "NT Transact Secondary" },
14655   { 0xA2, "NT Create AndX" },
14656   { 0xA3, "unknown-0xA3" },
14657   { 0xA4, "NT Cancel" },
14658   { 0xA5, "NT Rename" },
14659   { 0xA6, "unknown-0xA6" },
14660   { 0xA7, "unknown-0xA7" },
14661   { 0xA8, "unknown-0xA8" },
14662   { 0xA9, "unknown-0xA9" },
14663   { 0xAA, "unknown-0xAA" },
14664   { 0xAB, "unknown-0xAB" },
14665   { 0xAC, "unknown-0xAC" },
14666   { 0xAD, "unknown-0xAD" },
14667   { 0xAE, "unknown-0xAE" },
14668   { 0xAF, "unknown-0xAF" },
14669   { 0xB0, "unknown-0xB0" },
14670   { 0xB1, "unknown-0xB1" },
14671   { 0xB2, "unknown-0xB2" },
14672   { 0xB3, "unknown-0xB3" },
14673   { 0xB4, "unknown-0xB4" },
14674   { 0xB5, "unknown-0xB5" },
14675   { 0xB6, "unknown-0xB6" },
14676   { 0xB7, "unknown-0xB7" },
14677   { 0xB8, "unknown-0xB8" },
14678   { 0xB9, "unknown-0xB9" },
14679   { 0xBA, "unknown-0xBA" },
14680   { 0xBB, "unknown-0xBB" },
14681   { 0xBC, "unknown-0xBC" },
14682   { 0xBD, "unknown-0xBD" },
14683   { 0xBE, "unknown-0xBE" },
14684   { 0xBF, "unknown-0xBF" },
14685   { 0xC0, "Open Print File" },
14686   { 0xC1, "Write Print File" },
14687   { 0xC2, "Close Print File" },
14688   { 0xC3, "Get Print Queue" },
14689   { 0xC4, "unknown-0xC4" },
14690   { 0xC5, "unknown-0xC5" },
14691   { 0xC6, "unknown-0xC6" },
14692   { 0xC7, "unknown-0xC7" },
14693   { 0xC8, "unknown-0xC8" },
14694   { 0xC9, "unknown-0xC9" },
14695   { 0xCA, "unknown-0xCA" },
14696   { 0xCB, "unknown-0xCB" },
14697   { 0xCC, "unknown-0xCC" },
14698   { 0xCD, "unknown-0xCD" },
14699   { 0xCE, "unknown-0xCE" },
14700   { 0xCF, "unknown-0xCF" },
14701   { 0xD0, "Send Single Block Message" },
14702   { 0xD1, "Send Broadcast Message" },
14703   { 0xD2, "Forward User Name" },
14704   { 0xD3, "Cancel Forward" },
14705   { 0xD4, "Get Machine Name" },
14706   { 0xD5, "Send Start of Multi-block Message" },
14707   { 0xD6, "Send End of Multi-block Message" },
14708   { 0xD7, "Send Text of Multi-block Message" },
14709   { 0xD8, "SMBreadbulk" },
14710   { 0xD9, "SMBwritebulk" },
14711   { 0xDA, "SMBwritebulkdata" },
14712   { 0xDB, "unknown-0xDB" },
14713   { 0xDC, "unknown-0xDC" },
14714   { 0xDD, "unknown-0xDD" },
14715   { 0xDE, "unknown-0xDE" },
14716   { 0xDF, "unknown-0xDF" },
14717   { 0xE0, "unknown-0xE0" },
14718   { 0xE1, "unknown-0xE1" },
14719   { 0xE2, "unknown-0xE2" },
14720   { 0xE3, "unknown-0xE3" },
14721   { 0xE4, "unknown-0xE4" },
14722   { 0xE5, "unknown-0xE5" },
14723   { 0xE6, "unknown-0xE6" },
14724   { 0xE7, "unknown-0xE7" },
14725   { 0xE8, "unknown-0xE8" },
14726   { 0xE9, "unknown-0xE9" },
14727   { 0xEA, "unknown-0xEA" },
14728   { 0xEB, "unknown-0xEB" },
14729   { 0xEC, "unknown-0xEC" },
14730   { 0xED, "unknown-0xED" },
14731   { 0xEE, "unknown-0xEE" },
14732   { 0xEF, "unknown-0xEF" },
14733   { 0xF0, "unknown-0xF0" },
14734   { 0xF1, "unknown-0xF1" },
14735   { 0xF2, "unknown-0xF2" },
14736   { 0xF3, "unknown-0xF3" },
14737   { 0xF4, "unknown-0xF4" },
14738   { 0xF5, "unknown-0xF5" },
14739   { 0xF6, "unknown-0xF6" },
14740   { 0xF7, "unknown-0xF7" },
14741   { 0xF8, "unknown-0xF8" },
14742   { 0xF9, "unknown-0xF9" },
14743   { 0xFA, "unknown-0xFA" },
14744   { 0xFB, "unknown-0xFB" },
14745   { 0xFC, "unknown-0xFC" },
14746   { 0xFD, "unknown-0xFD" },
14747   { 0xFE, "SMBinvalid" },
14748   { 0xFF, "unknown-0xFF" },
14749   { 0x00, NULL },
14750 };
14751
14752 static char *decode_smb_name(unsigned char cmd)
14753 {
14754   return(smb_cmd_vals[cmd].strptr);
14755 }
14756
14757
14758
14759 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14760  * Everything TVBUFFIFIED above this line
14761  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14762
14763
14764 static void
14765 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14766 {
14767         conv_tables_t *ct = ctarg;
14768
14769         if (ct->unmatched)
14770                 g_hash_table_destroy(ct->unmatched);
14771         if (ct->matched)
14772                 g_hash_table_destroy(ct->matched);
14773         if (ct->tid_service)
14774                 g_hash_table_destroy(ct->tid_service);
14775 }
14776
14777 static void
14778 smb_init_protocol(void)
14779 {
14780         if (smb_saved_info_key_chunk)
14781                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14782         if (smb_saved_info_chunk)
14783                 g_mem_chunk_destroy(smb_saved_info_chunk);
14784         if (smb_nt_transact_info_chunk)
14785                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14786         if (smb_transact2_info_chunk)
14787                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14788         if (smb_transact_info_chunk)
14789                 g_mem_chunk_destroy(smb_transact_info_chunk);
14790
14791         /*
14792          * Free the hash tables attached to the conversation table
14793          * structures, and then free the list of conversation table
14794          * data structures (which doesn't free the data structures
14795          * themselves; that's done by destroying the chunk from
14796          * which they were allocated).
14797          */
14798         if (conv_tables) {
14799                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14800                 g_slist_free(conv_tables);
14801                 conv_tables = NULL;
14802         }
14803
14804         /*
14805          * Now destroy the chunk from which the conversation table
14806          * structures were allocated.
14807          */
14808         if (conv_tables_chunk)
14809                 g_mem_chunk_destroy(conv_tables_chunk);
14810
14811         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14812             sizeof(smb_saved_info_t),
14813             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14814             G_ALLOC_ONLY);
14815         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14816             sizeof(smb_saved_info_key_t),
14817             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14818             G_ALLOC_ONLY);
14819         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14820             sizeof(smb_nt_transact_info_t),
14821             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14822             G_ALLOC_ONLY);
14823         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14824             sizeof(smb_transact2_info_t),
14825             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14826             G_ALLOC_ONLY);
14827         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14828             sizeof(smb_transact_info_t),
14829             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14830             G_ALLOC_ONLY);
14831         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14832             sizeof(conv_tables_t),
14833             conv_tables_count * sizeof(conv_tables_t),
14834             G_ALLOC_ONLY);
14835 }
14836
14837 static const value_string errcls_types[] = {
14838   { SMB_SUCCESS, "Success"},
14839   { SMB_ERRDOS, "DOS Error"},
14840   { SMB_ERRSRV, "Server Error"},
14841   { SMB_ERRHRD, "Hardware Error"},
14842   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14843   { 0, NULL }
14844 };
14845
14846 const value_string DOS_errors[] = {
14847   {0, "Success"},
14848   {SMBE_insufficientbuffer, "Insufficient buffer"},
14849   {SMBE_badfunc, "Invalid function (or system call)"},
14850   {SMBE_badfile, "File not found (pathname error)"},
14851   {SMBE_badpath, "Directory not found"},
14852   {SMBE_nofids, "Too many open files"},
14853   {SMBE_noaccess, "Access denied"},
14854   {SMBE_badfid, "Invalid fid"},
14855   {SMBE_nomem,  "Out of memory"},
14856   {SMBE_badmem, "Invalid memory block address"},
14857   {SMBE_badenv, "Invalid environment"},
14858   {SMBE_badaccess, "Invalid open mode"},
14859   {SMBE_baddata, "Invalid data (only from ioctl call)"},
14860   {SMBE_res, "Reserved error code?"},
14861   {SMBE_baddrive, "Invalid drive"},
14862   {SMBE_remcd, "Attempt to delete current directory"},
14863   {SMBE_diffdevice, "Rename/move across different filesystems"},
14864   {SMBE_nofiles, "No more files found in file search"},
14865   {SMBE_badshare, "Share mode on file conflict with open mode"},
14866   {SMBE_lock, "Lock request conflicts with existing lock"},
14867   {SMBE_unsup, "Request unsupported, returned by Win 95"},
14868   {SMBE_nosuchshare, "Requested share does not exist"},
14869   {SMBE_filexists, "File in operation already exists"},
14870   {SMBE_cannotopen, "Cannot open the file specified"},
14871   {SMBE_unknownlevel, "Unknown info level"},
14872   {SMBE_invalidname, "Invalid name"},
14873   {SMBE_badpipe, "Named pipe invalid"},
14874   {SMBE_pipebusy, "All instances of pipe are busy"},
14875   {SMBE_pipeclosing, "Named pipe close in progress"},
14876   {SMBE_notconnected, "No process on other end of named pipe"},
14877   {SMBE_moredata, "More data to be returned"},
14878   {SMBE_baddirectory,  "Invalid directory name in a path."},
14879   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
14880   {SMBE_eas_nsup, "Extended attributes not supported"},
14881   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
14882   {SMBE_unknownipc, "Unknown IPC Operation"},
14883   {SMBE_noipc, "Don't support ipc"},
14884   {SMBE_alreadyexists, "File already exists"},
14885   {SMBE_unknownprinterdriver, "Unknown printer driver"},
14886   {SMBE_invalidprintername, "Invalid printer name"},
14887   {SMBE_printeralreadyexists, "Printer already exists"},
14888   {SMBE_invaliddatatype, "Invalid data type"},
14889   {SMBE_invalidenvironment, "Invalid environment"},
14890   {SMBE_printerdriverinuse, "Printer driver in use"},
14891   {SMBE_invalidparam, "Invalid parameter"},
14892   {SMBE_invalidformsize, "Invalid form size"},
14893   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
14894   {SMBE_invalidowner, "Invalid owner"},
14895   {SMBE_nomoreitems, "No more items"},
14896   {SMBE_serverunavailable, "Server unavailable"},
14897   {0, NULL}
14898   };
14899
14900 /* Error codes for the ERRSRV class */
14901
14902 static const value_string SRV_errors[] = {
14903   {SMBE_error, "Non specific error code"},
14904   {SMBE_badpw, "Bad password"},
14905   {SMBE_badtype, "Reserved"},
14906   {SMBE_access, "No permissions to perform the requested operation"},
14907   {SMBE_invnid, "TID invalid"},
14908   {SMBE_invnetname, "Invalid network name. Service not found"},
14909   {SMBE_invdevice, "Invalid device"},
14910   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14911   {SMBE_qfull, "Print queue full"},
14912   {SMBE_qtoobig, "Queued item too big"},
14913   {SMBE_qeof, "EOF on print queue dump"},
14914   {SMBE_invpfid, "Invalid print file in smb_fid"},
14915   {SMBE_smbcmd, "Unrecognised command"},
14916   {SMBE_srverror, "SMB server internal error"},
14917   {SMBE_filespecs, "Fid and pathname invalid combination"},
14918   {SMBE_badlink, "Bad link in request ???"},
14919   {SMBE_badpermits, "Access specified for a file is not valid"},
14920   {SMBE_badpid, "Bad process id in request"},
14921   {SMBE_setattrmode, "Attribute mode invalid"},
14922   {SMBE_paused, "Message server paused"},
14923   {SMBE_msgoff, "Not receiving messages"},
14924   {SMBE_noroom, "No room for message"},
14925   {SMBE_rmuns, "Too many remote usernames"},
14926   {SMBE_timeout, "Operation timed out"},
14927   {SMBE_noresource, "No resources currently available for request."},
14928   {SMBE_toomanyuids, "Too many userids"},
14929   {SMBE_baduid, "Bad userid"},
14930   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14931   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14932   {SMBE_contMPX, "Resume MPX mode"},
14933   {SMBE_badPW, "Bad Password???"},
14934   {SMBE_nosupport, "Operation not supported"},
14935   { 0, NULL}
14936 };
14937
14938 /* Error codes for the ERRHRD class */
14939
14940 static const value_string HRD_errors[] = {
14941   {SMBE_nowrite, "Read only media"},
14942   {SMBE_badunit, "Unknown device"},
14943   {SMBE_notready, "Drive not ready"},
14944   {SMBE_badcmd, "Unknown command"},
14945   {SMBE_data, "Data (CRC) error"},
14946   {SMBE_badreq, "Bad request structure length"},
14947   {SMBE_seek, "Seek error"},
14948   {SMBE_badmedia, "Unknown media type"},
14949   {SMBE_badsector, "Sector not found"},
14950   {SMBE_nopaper, "Printer out of paper"},
14951   {SMBE_write, "Write fault"},
14952   {SMBE_read, "Read fault"},
14953   {SMBE_general, "General failure"},
14954   {SMBE_badshare, "A open conflicts with an existing open"},
14955   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14956   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14957   {SMBE_FCBunavail, "No FCBs are available to process request"},
14958   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14959   {SMBE_diskfull, "Disk full???"},
14960   {0, NULL}
14961 };
14962
14963 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14964 {
14965
14966   switch (errcls) {
14967
14968   case SMB_SUCCESS:
14969
14970     return("No Error");   /* No error ??? */
14971     break;
14972
14973   case SMB_ERRDOS:
14974
14975     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14976     break;
14977
14978   case SMB_ERRSRV:
14979
14980     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14981     break;
14982
14983   case SMB_ERRHRD:
14984
14985     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14986     break;
14987
14988   default:
14989
14990     return("Unknown error class!");
14991
14992   }
14993
14994 }
14995
14996
14997 /* These are the MS country codes from
14998
14999         http://www.unicode.org/unicode/onlinedat/countries.html
15000
15001    For countries that share the same number, I choose to use only the
15002    name of the largest country. Apologies for this. If this offends you,
15003    here is the table to change that.
15004
15005    This also includes the code of 0 for "Default", which isn't in
15006    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15007    header file.  Presumably it means "don't override the setting
15008    on the user's machine".
15009
15010    Future versions of Microsoft's "winnls.h" header file might include
15011    additional codes; the current version matches the Unicode Consortium's
15012    table.
15013 */
15014 const value_string ms_country_codes[] = {
15015         {  0,   "Default"},
15016         {  1,   "USA"},
15017         {  2,   "Canada"},
15018         {  7,   "Russia"},
15019         { 20,   "Egypt"},
15020         { 27,   "South Africa"},
15021         { 30,   "Greece"},
15022         { 31,   "Netherlands"},
15023         { 32,   "Belgium"},
15024         { 33,   "France"},
15025         { 34,   "Spain"},
15026         { 36,   "Hungary"},
15027         { 39,   "Italy"},
15028         { 40,   "Romania"},
15029         { 41,   "Switzerland"},
15030         { 43,   "Austria"},
15031         { 44,   "United Kingdom"},
15032         { 45,   "Denmark"},
15033         { 46,   "Sweden"},
15034         { 47,   "Norway"},
15035         { 48,   "Poland"},
15036         { 49,   "Germany"},
15037         { 51,   "Peru"},
15038         { 52,   "Mexico"},
15039         { 54,   "Argentina"},
15040         { 55,   "Brazil"},
15041         { 56,   "Chile"},
15042         { 57,   "Colombia"},
15043         { 58,   "Venezuela"},
15044         { 60,   "Malaysia"},
15045         { 61,   "Australia"},
15046         { 62,   "Indonesia"},
15047         { 63,   "Philippines"},
15048         { 64,   "New Zealand"},
15049         { 65,   "Singapore"},
15050         { 66,   "Thailand"},
15051         { 81,   "Japan"},
15052         { 82,   "South Korea"},
15053         { 84,   "Viet Nam"},
15054         { 86,   "China"},
15055         { 90,   "Turkey"},
15056         { 91,   "India"},
15057         { 92,   "Pakistan"},
15058         {212,   "Morocco"},
15059         {213,   "Algeria"},
15060         {216,   "Tunisia"},
15061         {218,   "Libya"},
15062         {254,   "Kenya"},
15063         {263,   "Zimbabwe"},
15064         {298,   "Faroe Islands"},
15065         {351,   "Portugal"},
15066         {352,   "Luxembourg"},
15067         {353,   "Ireland"},
15068         {354,   "Iceland"},
15069         {355,   "Albania"},
15070         {358,   "Finland"},
15071         {359,   "Bulgaria"},
15072         {370,   "Lithuania"},
15073         {371,   "Latvia"},
15074         {372,   "Estonia"},
15075         {374,   "Armenia"},
15076         {375,   "Belarus"},
15077         {380,   "Ukraine"},
15078         {381,   "Serbia"},
15079         {385,   "Croatia"},
15080         {386,   "Slovenia"},
15081         {389,   "Macedonia"},
15082         {420,   "Czech Republic"},
15083         {421,   "Slovak Republic"},
15084         {501,   "Belize"},
15085         {502,   "Guatemala"},
15086         {503,   "El Salvador"},
15087         {504,   "Honduras"},
15088         {505,   "Nicaragua"},
15089         {506,   "Costa Rica"},
15090         {507,   "Panama"},
15091         {591,   "Bolivia"},
15092         {593,   "Ecuador"},
15093         {595,   "Paraguay"},
15094         {598,   "Uruguay"},
15095         {673,   "Brunei Darussalam"},
15096         {852,   "Hong Kong"},
15097         {853,   "Macau"},
15098         {886,   "Taiwan"},
15099         {960,   "Maldives"},
15100         {961,   "Lebanon"},
15101         {962,   "Jordan"},
15102         {963,   "Syria"},
15103         {964,   "Iraq"},
15104         {965,   "Kuwait"},
15105         {966,   "Saudi Arabia"},
15106         {967,   "Yemen"},
15107         {968,   "Oman"},
15108         {971,   "United Arab Emirates"},
15109         {972,   "Israel"},
15110         {973,   "Bahrain"},
15111         {974,   "Qatar"},
15112         {976,   "Mongolia"},
15113         {981,   "Iran"},
15114         {994,   "Azerbaijan"},
15115         {995,   "Georgia"},
15116         {996,   "Kyrgyzstan"},
15117
15118         {0,     NULL}
15119 };
15120
15121 /*
15122  * NT error codes.
15123  *
15124  * From
15125  *
15126  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15127  */
15128 const value_string NT_errors[] = {
15129   { 0x00000000, "STATUS_SUCCESS" },
15130   { 0x00000000, "STATUS_WAIT_0" },
15131   { 0x00000001, "STATUS_WAIT_1" },
15132   { 0x00000002, "STATUS_WAIT_2" },
15133   { 0x00000003, "STATUS_WAIT_3" },
15134   { 0x0000003F, "STATUS_WAIT_63" },
15135   { 0x00000080, "STATUS_ABANDONED" },
15136   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15137   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15138   { 0x000000C0, "STATUS_USER_APC" },
15139   { 0x00000100, "STATUS_KERNEL_APC" },
15140   { 0x00000101, "STATUS_ALERTED" },
15141   { 0x00000102, "STATUS_TIMEOUT" },
15142   { 0x00000103, "STATUS_PENDING" },
15143   { 0x00000104, "STATUS_REPARSE" },
15144   { 0x00000105, "STATUS_MORE_ENTRIES" },
15145   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15146   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15147   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15148   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15149   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15150   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15151   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15152   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15153   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15154   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15155   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15156   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15157   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15158   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15159   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15160   { 0x00000116, "STATUS_CRASH_DUMP" },
15161   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15162   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15163   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15164   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15165   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15166   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15167   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15168   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15169   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15170   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15171   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15172   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15173   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15174   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15175   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15176   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15177   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15178   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15179   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15180   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15181   { 0x40000012, "STATUS_EVENT_DONE" },
15182   { 0x40000013, "STATUS_EVENT_PENDING" },
15183   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15184   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15185   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15186   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15187   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15188   { 0x40000019, "STATUS_WAS_LOCKED" },
15189   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15190   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15191   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15192   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15193   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15194   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15195   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15196   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15197   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15198   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15199   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15200   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15201   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15202   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15203   { 0x80000003, "STATUS_BREAKPOINT" },
15204   { 0x80000004, "STATUS_SINGLE_STEP" },
15205   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15206   { 0x80000006, "STATUS_NO_MORE_FILES" },
15207   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15208   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15209   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15210   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15211   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15212   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15213   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15214   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15215   { 0x80000011, "STATUS_DEVICE_BUSY" },
15216   { 0x80000012, "STATUS_NO_MORE_EAS" },
15217   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15218   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15219   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15220   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15221   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15222   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15223   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15224   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15225   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15226   { 0x8000001D, "STATUS_BUS_RESET" },
15227   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15228   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15229   { 0x80000020, "STATUS_MEDIA_CHECK" },
15230   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15231   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15232   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15233   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15234   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15235   { 0x80000026, "STATUS_LONGJUMP" },
15236   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15237   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15238   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15239   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15240   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15241   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15242   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15243   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15244   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15245   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15246   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15247   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15248   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15249   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15250   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15251   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15252   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15253   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15254   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15255   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15256   { 0xC000000B, "STATUS_INVALID_CID" },
15257   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15258   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15259   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15260   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15261   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15262   { 0xC0000011, "STATUS_END_OF_FILE" },
15263   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15264   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15265   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15266   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15267   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15268   { 0xC0000017, "STATUS_NO_MEMORY" },
15269   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15270   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15271   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15272   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15273   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15274   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15275   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15276   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15277   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15278   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15279   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15280   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15281   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15282   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15283   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15284   { 0xC0000027, "STATUS_UNWIND" },
15285   { 0xC0000028, "STATUS_BAD_STACK" },
15286   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15287   { 0xC000002A, "STATUS_NOT_LOCKED" },
15288   { 0xC000002B, "STATUS_PARITY_ERROR" },
15289   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15290   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15291   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15292   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15293   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15294   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15295   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15296   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15297   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15298   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15299   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15300   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15301   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15302   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15303   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15304   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15305   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15306   { 0xC000003E, "STATUS_DATA_ERROR" },
15307   { 0xC000003F, "STATUS_CRC_ERROR" },
15308   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15309   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15310   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15311   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15312   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15313   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15314   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15315   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15316   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15317   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15318   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15319   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15320   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15321   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15322   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15323   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15324   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15325   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15326   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15327   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15328   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15329   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15330   { 0xC0000056, "STATUS_DELETE_PENDING" },
15331   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15332   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15333   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15334   { 0xC000005A, "STATUS_INVALID_OWNER" },
15335   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15336   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15337   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15338   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15339   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15340   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15341   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15342   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15343   { 0xC0000063, "STATUS_USER_EXISTS" },
15344   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15345   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15346   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15347   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15348   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15349   { 0xC0000069, "STATUS_LAST_ADMIN" },
15350   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15351   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15352   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15353   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15354   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15355   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15356   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15357   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15358   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15359   { 0xC0000073, "STATUS_NONE_MAPPED" },
15360   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15361   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15362   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15363   { 0xC0000077, "STATUS_INVALID_ACL" },
15364   { 0xC0000078, "STATUS_INVALID_SID" },
15365   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15366   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15367   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15368   { 0xC000007C, "STATUS_NO_TOKEN" },
15369   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15370   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15371   { 0xC000007F, "STATUS_DISK_FULL" },
15372   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15373   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15374   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15375   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15376   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15377   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15378   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15379   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15380   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15381   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15382   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15383   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15384   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15385   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15386   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15387   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15388   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15389   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15390   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15391   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15392   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15393   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15394   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15395   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15396   { 0xC0000098, "STATUS_FILE_INVALID" },
15397   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15398   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15399   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15400   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15401   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15402   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15403   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15404   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15405   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15406   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15407   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15408   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15409   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15410   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15411   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15412   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15413   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15414   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15415   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15416   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15417   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15418   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15419   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15420   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15421   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15422   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15423   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15424   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15425   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15426   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15427   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15428   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15429   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15430   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15431   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15432   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15433   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15434   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15435   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15436   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15437   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15438   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15439   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15440   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15441   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15442   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15443   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15444   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15445   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15446   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15447   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15448   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15449   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15450   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15451   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15452   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15453   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15454   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15455   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15456   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15457   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15458   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15459   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15460   { 0xC00000D8, "STATUS_CANT_WAIT" },
15461   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15462   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15463   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15464   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15465   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15466   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15467   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15468   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15469   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15470   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15471   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15472   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15473   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15474   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15475   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15476   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15477   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15478   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15479   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15480   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15481   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15482   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15483   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15484   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15485   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15486   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15487   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15488   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15489   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15490   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15491   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15492   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15493   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15494   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15495   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15496   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15497   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15498   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15499   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15500   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15501   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15502   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15503   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15504   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15505   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15506   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15507   { 0xC0000107, "STATUS_FILES_OPEN" },
15508   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15509   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15510   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15511   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15512   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15513   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15514   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15515   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15516   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15517   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15518   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15519   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15520   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15521   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15522   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15523   { 0xC0000117, "STATUS_NO_LDT" },
15524   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15525   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15526   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15527   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15528   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15529   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15530   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15531   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15532   { 0xC0000120, "STATUS_CANCELLED" },
15533   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15534   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15535   { 0xC0000123, "STATUS_FILE_DELETED" },
15536   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15537   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15538   { 0xC0000126, "STATUS_SPECIAL_USER" },
15539   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15540   { 0xC0000128, "STATUS_FILE_CLOSED" },
15541   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15542   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15543   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15544   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15545   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15546   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15547   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15548   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15549   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15550   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15551   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15552   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15553   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15554   { 0xC0000136, "STATUS_OPEN_FAILED" },
15555   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15556   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15557   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15558   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15559   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15560   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15561   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15562   { 0xC000013E, "STATUS_LINK_FAILED" },
15563   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15564   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15565   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15566   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15567   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15568   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15569   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15570   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15571   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15572   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15573   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15574   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15575   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15576   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15577   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15578   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15579   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15580   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15581   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15582   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15583   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15584   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15585   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15586   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15587   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15588   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15589   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15590   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15591   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15592   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15593   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15594   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15595   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15596   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15597   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15598   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15599   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15600   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15601   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15602   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15603   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15604   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15605   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15606   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15607   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15608   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15609   { 0xC000016D, "STATUS_FT_ORPHANING" },
15610   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15611   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15612   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15613   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15614   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15615   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15616   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15617   { 0xC0000178, "STATUS_NO_MEDIA" },
15618   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15619   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15620   { 0xC000017C, "STATUS_KEY_DELETED" },
15621   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15622   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15623   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15624   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15625   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15626   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15627   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15628   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15629   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15630   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15631   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15632   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15633   { 0xC0000189, "STATUS_TOO_LATE" },
15634   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15635   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15636   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15637   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15638   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15639   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15640   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15641   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15642   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15643   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15644   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15645   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15646   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15647   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15648   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15649   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15650   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15651   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15652   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15653   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15654   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15655   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15656   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15657   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15658   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15659   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15660   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15661   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15662   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15663   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15664   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15665   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15666   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15667   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15668   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15669   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15670   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15671   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15672   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15673   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15674   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15675   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15676   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15677   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15678   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15679   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15680   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15681   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15682   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15683   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15684   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15685   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15686   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15687   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15688   { 0xC0000225, "STATUS_NOT_FOUND" },
15689   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15690   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15691   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15692   { 0xC0000229, "STATUS_FAIL_CHECK" },
15693   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15694   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15695   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15696   { 0xC000022D, "STATUS_RETRY" },
15697   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15698   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15699   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15700   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15701   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15702   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15703   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15704   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15705   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15706   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15707   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15708   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15709   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15710   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15711   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15712   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15713   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15714   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15715   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15716   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15717   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15718   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15719   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15720   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15721   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15722   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15723   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15724   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15725   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15726   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15727   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15728   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15729   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15730   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15731   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15732   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15733   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15734   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15735   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15736   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15737   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15738   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15739   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15740   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15741   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15742   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15743   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15744   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15745   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15746   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15747   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15748   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15749   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15750   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15751   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15752   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15753   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15754   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15755   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15756   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15757   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15758   { 0xC0000272, "STATUS_NO_MATCH" },
15759   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15760   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15761   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15762   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15763   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15764   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15765   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15766   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15767   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15768   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15769   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15770   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15771   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15772   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15773   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15774   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15775   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15776   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15777   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15778   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15779   { 0xC000028E, "STATUS_NO_EFS" },
15780   { 0xC000028F, "STATUS_WRONG_EFS" },
15781   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15782   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15783   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15784   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15785   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15786   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15787   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15788   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15789   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15790   { 0xC0000299, "STATUS_SHARED_POLICY" },
15791   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15792   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15793   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15794   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15795   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15796   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15797   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15798   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15799   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15800   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15801   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15802   { 0xC00002A5, "STATUS_DS_BUSY" },
15803   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15804   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15805   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15806   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15807   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15808   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15809   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15810   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15811   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15812   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15813   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15814   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15815   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15816   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15817   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15818   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15819   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15820   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15821   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15822   { 0xC00002B9, "STATUS_NOINTERFACE" },
15823   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15824   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15825   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15826   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15827   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15828   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15829   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15830   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15831   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15832   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15833   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15834   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15835   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15836   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15837   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15838   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15839   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15840   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15841   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15842   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15843   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15844   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
15845   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
15846   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
15847   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
15848   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
15849   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
15850   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
15851   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
15852   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
15853   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
15854   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
15855   { 0xC00002E1, "STATUS_DS_CANT_START" },
15856   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
15857   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
15858   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
15859   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
15860   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
15861   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
15862   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
15863   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
15864   { 0xC0009898, "STATUS_WOW_ASSERTION" },
15865   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
15866   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
15867   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
15868   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
15869   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
15870   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
15871   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
15872   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
15873   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
15874   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
15875   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
15876   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
15877   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
15878   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
15879   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
15880   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
15881   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
15882   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
15883   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
15884   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
15885   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
15886   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
15887   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
15888   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
15889   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
15890   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
15891   { 0xC002001B, "RPC_NT_CALL_FAILED" },
15892   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
15893   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
15894   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
15895   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
15896   { 0xC0020022, "RPC_NT_INVALID_TAG" },
15897   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
15898   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
15899   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
15900   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
15901   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
15902   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
15903   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
15904   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
15905   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
15906   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
15907   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
15908   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
15909   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
15910   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
15911   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
15912   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
15913   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
15914   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
15915   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
15916   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
15917   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
15918   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
15919   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
15920   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
15921   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
15922   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
15923   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
15924   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
15925   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
15926   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
15927   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
15928   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
15929   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
15930   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
15931   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
15932   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
15933   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
15934   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
15935   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
15936   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
15937   { 0xC002100A, "RPC_P_SEND_FAILED" },
15938   { 0xC002100B, "RPC_P_TIMEOUT" },
15939   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
15940   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
15941   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
15942   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
15943   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
15944   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
15945   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
15946   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
15947   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
15948   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
15949   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
15950   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
15951   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
15952   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
15953   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
15954   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
15955   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
15956   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
15957   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
15958   { 0xC002004C, "EPT_NT_CANT_CREATE" },
15959   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
15960   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
15961   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
15962   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
15963   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
15964   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
15965   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15966   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15967   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15968   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15969   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15970   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15971   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15972   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15973   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15974   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15975   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15976   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15977   { 0,          NULL }
15978 };
15979
15980
15981
15982 static const true_false_string tfs_smb_flags_lock = {
15983         "Lock&Read, Write&Unlock are supported",
15984         "Lock&Read, Write&Unlock are not supported"
15985 };
15986 static const true_false_string tfs_smb_flags_receive_buffer = {
15987         "Receive buffer has been posted",
15988         "Receive buffer has not been posted"
15989 };
15990 static const true_false_string tfs_smb_flags_caseless = {
15991         "Path names are caseless",
15992         "Path names are case sensitive"
15993 };
15994 static const true_false_string tfs_smb_flags_canon = {
15995         "Pathnames are canonicalized",
15996         "Pathnames are not canonicalized"
15997 };
15998 static const true_false_string tfs_smb_flags_oplock = {
15999         "OpLock requested/granted",
16000         "OpLock not requested/granted"
16001 };
16002 static const true_false_string tfs_smb_flags_notify = {
16003         "Notify client on all modifications",
16004         "Notify client only on open"
16005 };
16006 static const true_false_string tfs_smb_flags_response = {
16007         "Message is a response to the client/redirector",
16008         "Message is a request to the server"
16009 };
16010
16011 static int
16012 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16013 {
16014         guint8 mask;
16015         proto_item *item = NULL;
16016         proto_tree *tree = NULL;
16017
16018         mask = tvb_get_guint8(tvb, offset);
16019
16020         if(parent_tree){
16021                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16022                         "Flags: 0x%02x", mask);
16023                 tree = proto_item_add_subtree(item, ett_smb_flags);
16024         }
16025         proto_tree_add_boolean(tree, hf_smb_flags_response,
16026                 tvb, offset, 1, mask);
16027         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16028                 tvb, offset, 1, mask);
16029         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16030                 tvb, offset, 1, mask);
16031         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16032                 tvb, offset, 1, mask);
16033         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16034                 tvb, offset, 1, mask);
16035         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16036                 tvb, offset, 1, mask);
16037         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16038                 tvb, offset, 1, mask);
16039         offset += 1;
16040         return offset;
16041 }
16042
16043
16044
16045 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16046         "Long file names are allowed in the response",
16047         "Long file names are not allowed in the response"
16048 };
16049 static const true_false_string tfs_smb_flags2_ea = {
16050         "Extended attributes are supported",
16051         "Extended attributes are not supported"
16052 };
16053 static const true_false_string tfs_smb_flags2_sec_sig = {
16054         "Security signatures are supported",
16055         "Security signatures are not supported"
16056 };
16057 static const true_false_string tfs_smb_flags2_long_names_used = {
16058         "Path names in request are long file names",
16059         "Path names in request are not long file names"
16060 };
16061 static const true_false_string tfs_smb_flags2_esn = {
16062         "Extended security negotiation is supported",
16063         "Extended security negotiation is not supported"
16064 };
16065 static const true_false_string tfs_smb_flags2_dfs = {
16066         "Resolve pathnames with Dfs",
16067         "Don't resolve pathnames with Dfs"
16068 };
16069 static const true_false_string tfs_smb_flags2_roe = {
16070         "Permit reads if execute-only",
16071         "Don't permit reads if execute-only"
16072 };
16073 static const true_false_string tfs_smb_flags2_nt_error = {
16074         "Error codes are NT error codes",
16075         "Error codes are DOS error codes"
16076 };
16077 static const true_false_string tfs_smb_flags2_string = {
16078         "Strings are Unicode",
16079         "Strings are ASCII"
16080 };
16081 static int
16082 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16083 {
16084         guint16 mask;
16085         proto_item *item = NULL;
16086         proto_tree *tree = NULL;
16087
16088         mask = tvb_get_letohs(tvb, offset);
16089
16090         if(parent_tree){
16091                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16092                         "Flags2: 0x%04x", mask);
16093                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16094         }
16095
16096         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16097                 tvb, offset, 2, mask);
16098         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16099                 tvb, offset, 2, mask);
16100         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16101                 tvb, offset, 2, mask);
16102         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16103                 tvb, offset, 2, mask);
16104         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16105                 tvb, offset, 2, mask);
16106         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16107                 tvb, offset, 2, mask);
16108         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16109                 tvb, offset, 2, mask);
16110         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16111                 tvb, offset, 2, mask);
16112         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16113                 tvb, offset, 2, mask);
16114
16115         offset += 2;
16116         return offset;
16117 }
16118
16119
16120
16121 #define SMB_FLAGS_DIRN 0x80
16122
16123
16124 static void
16125 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16126 {
16127         int offset = 0;
16128         proto_item *item = NULL, *hitem = NULL;
16129         proto_tree *tree = NULL, *htree = NULL;
16130         guint8          flags;
16131         guint16         flags2;
16132         static smb_info_t       si_arr[20];
16133         static int si_counter=0;
16134         smb_info_t              *si;
16135         smb_saved_info_t *sip = NULL;
16136         smb_saved_info_key_t key;
16137         smb_saved_info_key_t *new_key;
16138         guint32 nt_status = 0;
16139         guint8 errclass = 0;
16140         guint16 errcode = 0;
16141         guint32 pid_mid;
16142         conversation_t *conversation;
16143         nstime_t ns;
16144
16145         si_counter++;
16146         if(si_counter==20){
16147                 si_counter=0;
16148         }
16149         si=&si_arr[si_counter];
16150
16151         top_tree=parent_tree;
16152
16153         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16154                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16155         }
16156         if (check_col(pinfo->cinfo, COL_INFO)){
16157                 col_clear(pinfo->cinfo, COL_INFO);
16158         }
16159
16160         /* start off using the local variable, we will allocate a new one if we
16161            need to*/
16162         si->cmd = tvb_get_guint8(tvb, offset+4);
16163         flags = tvb_get_guint8(tvb, offset+9);
16164         /*
16165          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16166          * the direction flag appears never to be set, even for what appear
16167          * to be replies.  Do some SMB servers fail to set that flag,
16168          * under the assumption that the client knows it's a reply because
16169          * it received it?
16170          */
16171         si->request = !(flags&SMB_FLAGS_DIRN);
16172         flags2 = tvb_get_letohs(tvb, offset+10);
16173         if(flags2 & 0x8000){
16174                 si->unicode = TRUE; /* Mark them as Unicode */
16175         } else {
16176                 si->unicode = FALSE;
16177         }
16178         si->tid = tvb_get_letohs(tvb, offset+24);
16179         si->pid = tvb_get_letohs(tvb, offset+26);
16180         si->uid = tvb_get_letohs(tvb, offset+28);
16181         si->mid = tvb_get_letohs(tvb, offset+30);
16182         pid_mid = (si->pid << 16) | si->mid;
16183         si->info_level = -1;
16184         si->info_count = -1;
16185
16186         if (parent_tree) {
16187                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16188                         -1, FALSE);
16189                 tree = proto_item_add_subtree(item, ett_smb);
16190
16191                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16192                         "SMB Header");
16193
16194                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16195         }
16196
16197         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16198         offset += 4;  /* Skip the marker */
16199
16200         /* find which conversation we are part of and get the tables for that
16201            conversation*/
16202         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16203                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16204         if(!conversation){
16205                 /* OK this is a new conversation so lets create it */
16206                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16207                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16208         }
16209         /* see if we already have the smb data for this conversation */
16210         si->ct=conversation_get_proto_data(conversation, proto_smb);
16211         if(!si->ct){
16212                 /* No, not yet. create it and attach it to the conversation */
16213                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16214                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16215                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16216                         smb_saved_info_equal_matched);
16217                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16218                         smb_saved_info_equal_unmatched);
16219                 si->ct->tid_service=g_hash_table_new(
16220                         smb_saved_info_hash_unmatched,
16221                         smb_saved_info_equal_unmatched);
16222                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16223         }
16224
16225         if( (si->request)
16226             &&  (si->mid==0)
16227             &&  (si->uid==0)
16228             &&  (si->pid==0)
16229             &&  (si->tid==0) ){
16230                 /* this is a broadcast SMB packet, there will not be a reply.
16231                    We dont need to do anything
16232                 */
16233                 si->unidir = TRUE;
16234         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16235                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16236                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16237                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16238                 /* Ok, we got a special request type. This request is either
16239                    an NT Cancel or a continuation relative to a real request
16240                    in an earlier packet.  In either case, we don't expect any
16241                    responses to this packet.  For continuations, any later
16242                    responses we see really just belong to the original request.
16243                    Anyway, we want to remember this packet somehow and
16244                    remember which original request it is associated with so
16245                    we can say nice things such as "This is a Cancellation to
16246                    the request in frame x", but we don't want the
16247                    request/response matching to get messed up.
16248
16249                    The only thing we do in this case is trying to find which original
16250                    request we match with and insert an entry for this "special"
16251                    request for later reference. We continue to reference the original
16252                    requests smb_saved_info_t but we dont touch it or change anything
16253                    in it.
16254                 */
16255
16256                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16257
16258                 if(!pinfo->fd->flags.visited){
16259                         /* try to find which original call we match and if we
16260                            find it add us to the matched table. Dont touch
16261                            anything else since we dont want this one to mess
16262                            up the request/response matching. We still consider
16263                            the initial call the real request and this is only
16264                            some sort of continuation.
16265                         */
16266                         /* we only check the unmatched table and assume that the
16267                            last seen MID matching ours is the right one.
16268                            This can fail but is better than nothing
16269                         */
16270                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16271                         if(sip!=NULL){
16272                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16273                                 new_key->frame = pinfo->fd->num;
16274                                 new_key->pid_mid = pid_mid;
16275                                 g_hash_table_insert(si->ct->matched, new_key,
16276                                     sip);
16277                         }
16278                 } else {
16279                         /* we have seen this packet before; check the
16280                            matching table
16281                         */
16282                         key.frame = pinfo->fd->num;
16283                         key.pid_mid = pid_mid;
16284                         sip=g_hash_table_lookup(si->ct->matched, &key);
16285                         if(sip==NULL){
16286                         /*
16287                           We didn't find it.
16288                           Too bad, unfortunately there is not really much we can
16289                           do now since this means that we never saw the initial
16290                           request.
16291                          */
16292                         }
16293                 }
16294
16295
16296                 if(sip && sip->frame_req){
16297                         switch(si->cmd){
16298                         case SMB_COM_NT_CANCEL:
16299                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16300                                                     tvb, 0, 0, sip->frame_req);
16301                                 break;
16302                         case SMB_COM_TRANSACTION_SECONDARY:
16303                         case SMB_COM_TRANSACTION2_SECONDARY:
16304                         case SMB_COM_NT_TRANSACT_SECONDARY:
16305                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16306                                                     tvb, 0, 0, sip->frame_req);
16307                                 break;
16308                         }
16309                 } else {
16310                         switch(si->cmd){
16311                         case SMB_COM_NT_CANCEL:
16312                                 proto_tree_add_text(htree, tvb, 0, 0,
16313                                                     "Cancellation to: <unknown frame>");
16314                                 break;
16315                         case SMB_COM_TRANSACTION_SECONDARY:
16316                         case SMB_COM_TRANSACTION2_SECONDARY:
16317                         case SMB_COM_NT_TRANSACT_SECONDARY:
16318                                 proto_tree_add_text(htree, tvb, 0, 0,
16319                                                     "Continuation to: <unknown frame>");
16320                                 break;
16321                         }
16322                 }
16323         } else { /* normal bidirectional request or response */
16324                 si->unidir = FALSE;
16325
16326                 if(!pinfo->fd->flags.visited){
16327                         /* first see if we find an unmatched smb "equal" to
16328                            the current one
16329                         */
16330                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16331                         if(sip!=NULL){
16332                                 gboolean cmd_match=FALSE;
16333
16334                                 /*
16335                                  * Make sure the SMB we found was the
16336                                  * same command, or a different command
16337                                  * that's another valid type of reply
16338                                  * to that command.
16339                                  */
16340                                 if(si->cmd==sip->cmd){
16341                                         cmd_match=TRUE;
16342                                 }
16343                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16344                                         cmd_match=TRUE;
16345                                 }
16346                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16347                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16348                                         cmd_match=TRUE;
16349                                 }
16350                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16351                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16352                                         cmd_match=TRUE;
16353                                 }
16354                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16355                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16356                                         cmd_match=TRUE;
16357                                 }
16358
16359                                 if( (si->request) || (!cmd_match) ) {
16360                                         /* If we are processing an SMB request but there was already
16361                                            another "identical" smb resuest we had not matched yet.
16362                                            This must mean that either we have a retransmission or that the
16363                                            response to the previous one was lost and the client has reused
16364                                            the MID for this conversation. In either case it's not much more
16365                                            we can do than forget the old request and concentrate on the
16366                                            present one instead.
16367
16368                                            We also do this cleanup if we see that the cmd in the original
16369                                            request in sip->cmd is not compatible with the current cmd.
16370                                            This is to prevent matching errors such as if there were two
16371                                            SMBs of different cmds but with identical MID and PID values and
16372                                            if ethereal lost the first reply and the second request.
16373                                         */
16374                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16375                                         sip=NULL; /* XXX should free it as well */
16376                                 } else {
16377                                         /* we have found a response to some request we have seen earlier.
16378                                            What we do now depends on whether this is the first response
16379                                            to that request we see (id frame_res==0) or not.
16380                                         */
16381                                         if(sip->frame_res==0){
16382                                                 /* ok it is the first response we have seen to this packet */
16383                                                 sip->frame_res = pinfo->fd->num;
16384                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16385                                                 new_key->frame = sip->frame_res;
16386                                                 new_key->pid_mid = pid_mid;
16387                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16388                                         } else {
16389                                                 /* We have already seen another response to this MID.
16390                                                    Since the MID in reality is only something like 10 bits
16391                                                    this probably means that we just have a MID that is being
16392                                                    reused due to the small MID space and that this is a new
16393                                                    command we did not see the original request for.
16394                                                 */
16395                                                 sip=NULL;
16396                                         }
16397                                 }
16398                         }
16399                         if(si->request){
16400                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16401                                 sip->frame_req = pinfo->fd->num;
16402                                 sip->frame_res = 0;
16403                                 sip->req_time.secs=pinfo->fd->abs_secs;
16404                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16405                                 sip->flags = 0;
16406                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16407                                     == (void *)TID_IPC) {
16408                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16409                                 }
16410                                 sip->cmd = si->cmd;
16411                                 sip->extra_info = NULL;
16412                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16413                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16414                                 new_key->frame = sip->frame_req;
16415                                 new_key->pid_mid = pid_mid;
16416                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16417                         }
16418                 } else {
16419                         /* we have seen this packet before; check the
16420                            matching table.
16421                            If we haven't yet seen the reply, we won't
16422                            find the info for it; we don't need it, as
16423                            we only use it to save information, and, as
16424                            we've seen this packet before, we've already
16425                            saved the information.
16426                         */
16427                         key.frame = pinfo->fd->num;
16428                         key.pid_mid = pid_mid;
16429                         sip=g_hash_table_lookup(si->ct->matched, &key);
16430                 }
16431         }
16432
16433         /*
16434          * Pass the "sip" on to subdissectors through "si".
16435          */
16436         si->sip = sip;
16437
16438         if (sip != NULL) {
16439                 /*
16440                  * Put in fields for the frame number of the frame to which
16441                  * this is a response or the frame with the response to this
16442                  * frame - if we know the frame number (i.e., it's not 0).
16443                  */
16444                 if(si->request){
16445                         if (sip->frame_res != 0)
16446                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16447                 } else {
16448                         if (sip->frame_req != 0) {
16449                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16450                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16451                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16452                                 if(ns.nsecs<0){
16453                                         ns.nsecs+=1000000000;
16454                                         ns.secs--;
16455                                 }
16456                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16457                                     0, 0, &ns);
16458                         }
16459                 }
16460         }
16461
16462         /* smb command */
16463         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);
16464         offset += 1;
16465
16466         if(flags2 & 0x4000){
16467                 /* handle NT 32 bit error code */
16468
16469                 nt_status = tvb_get_letohl(tvb, offset);
16470
16471                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16472                         TRUE);
16473                 offset += 4;
16474
16475         } else {
16476                 /* handle DOS error code & class */
16477                 errclass = tvb_get_guint8(tvb, offset);
16478                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16479                         errclass);
16480                 offset += 1;
16481
16482                 /* reserved byte */
16483                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16484                 offset += 1;
16485
16486                 /* error code */
16487                 /* XXX - the type of this field depends on the value of
16488                  * "errcls", so there is isn't a single value_string array
16489                  * fo it, so there can't be a single field for it.
16490                  */
16491                 errcode = tvb_get_letohs(tvb, offset);
16492                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16493                         offset, 2, errcode, "Error Code: %s",
16494                         decode_smb_error(errclass, errcode));
16495                 offset += 2;
16496         }
16497
16498         /* flags */
16499         offset = dissect_smb_flags(tvb, htree, offset);
16500
16501         /* flags2 */
16502         offset = dissect_smb_flags2(tvb, htree, offset);
16503
16504         /*
16505          * The document at
16506          *
16507          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16508          *
16509          * (a text version of "Microsoft Networks SMB FILE SHARING
16510          * PROTOCOL, Document Version 6.0p") says that:
16511          *
16512          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16513          *      the "High Part of PID";
16514          *
16515          *      the next four bytes are reserved;
16516          *
16517          *      the next four bytes are, for SMB-over-IPX (with no
16518          *      NetBIOS involved) two bytes of Session ID and two bytes
16519          *      of SequenceNumber.
16520          *
16521          * Network Monitor 2.x dissects the four bytes before the Session ID
16522          * as a "Key", and the two bytes after the SequenceNumber as
16523          * a "Group ID".
16524          *
16525          * The "High Part of PID" has been seen in calls other than NT
16526          * Create and X, although most of them appear to be I/O on DCE RPC
16527          * pipes opened with the NT Create and X in question.
16528          */
16529         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16530         offset += 2;
16531
16532         if (pinfo->ptype == PT_IPX &&
16533             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16534              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16535              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16536                 /*
16537                  * This is SMB-over-IPX.
16538                  * XXX - do we have to worry about "sequenced commands",
16539                  * as per the Samba document?  They say that for
16540                  * "unsequenced commands" (with a sequence number of 0),
16541                  * the Mid must be unique, but perhaps the Mid doesn't
16542                  * have to be unique for sequenced commands.  In at least
16543                  * one capture with SMB-over-IPX, however, the Mids
16544                  * are unique even for sequenced commands.
16545                  */
16546                 /* Key */
16547                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16548                     TRUE);
16549                 offset += 4;
16550
16551                 /* Session ID */
16552                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16553                     TRUE);
16554                 offset += 2;
16555
16556                 /* Sequence number */
16557                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16558                     TRUE);
16559                 offset += 2;
16560
16561                 /* Group ID */
16562                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16563                     TRUE);
16564                 offset += 2;
16565         } else {
16566                 /*
16567                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16568                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16569                  * bytes after the "High part of PID" are an 8-byte
16570                  * signature ...
16571                  */
16572                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16573                 offset += 8;
16574
16575                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16576                 offset += 2;
16577         }
16578
16579         /* TID */
16580         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16581         offset += 2;
16582
16583         /* PID */
16584         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16585         offset += 2;
16586
16587         /* UID */
16588         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16589         offset += 2;
16590
16591         /* MID */
16592         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16593         offset += 2;
16594
16595         pinfo->private_data = si;
16596
16597         /* tap the packet before the dissectors are called so we still get
16598            the tap listener called even if there is an exception.
16599         */
16600         tap_queue_packet(smb_tap, pinfo, si);
16601         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16602
16603         /* Append error info from this packet to info string. */
16604         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16605                 if (flags2 & 0x4000) {
16606                         /*
16607                          * The status is an NT status code; was there
16608                          * an error?
16609                          */
16610                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16611                                 /*
16612                                  * Yes.
16613                                  */
16614                                 col_append_fstr(
16615                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16616                                         val_to_str(nt_status, NT_errors,
16617                                             "Unknown (0x%08X)"));
16618                         }
16619                 } else {
16620                         /*
16621                          * The status is a DOS error class and code; was
16622                          * there an error?
16623                          */
16624                         if (errclass != SMB_SUCCESS) {
16625                                 /*
16626                                  * Yes.
16627                                  */
16628                                 col_append_fstr(
16629                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16630                                         decode_smb_error(errclass, errcode));
16631                         }
16632                 }
16633         }
16634 }
16635
16636 static gboolean
16637 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16638 {
16639         /* must check that this really is a smb packet */
16640         if (!tvb_bytes_exist(tvb, 0, 4))
16641                 return FALSE;
16642
16643         if( (tvb_get_guint8(tvb, 0) != 0xff)
16644             || (tvb_get_guint8(tvb, 1) != 'S')
16645             || (tvb_get_guint8(tvb, 2) != 'M')
16646             || (tvb_get_guint8(tvb, 3) != 'B') ){
16647                 return FALSE;
16648         }
16649
16650         dissect_smb(tvb, pinfo, parent_tree);
16651         return TRUE;
16652 }
16653
16654 void
16655 proto_register_smb(void)
16656 {
16657         static hf_register_info hf[] = {
16658         { &hf_smb_cmd,
16659                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16660                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16661
16662         { &hf_smb_word_count,
16663                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16664                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16665
16666         { &hf_smb_byte_count,
16667                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16668                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16669
16670         { &hf_smb_response_to,
16671                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16672                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16673
16674         { &hf_smb_time,
16675                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16676                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16677
16678         { &hf_smb_response_in,
16679                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16680                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16681
16682         { &hf_smb_continuation_to,
16683                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16684                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16685
16686         { &hf_smb_nt_status,
16687                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16688                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16689
16690         { &hf_smb_error_class,
16691                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16692                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16693
16694         { &hf_smb_error_code,
16695                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16696                 NULL, 0, "DOS Error Code", HFILL }},
16697
16698         { &hf_smb_reserved,
16699                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16700                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16701
16702         { &hf_smb_sig,
16703                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16704                 NULL, 0, "Signature bytes", HFILL }},
16705
16706         { &hf_smb_key,
16707                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16708                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16709
16710         { &hf_smb_session_id,
16711                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16712                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16713
16714         { &hf_smb_sequence_num,
16715                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16716                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16717
16718         { &hf_smb_group_id,
16719                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16720                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16721
16722         { &hf_smb_pid,
16723                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16724                 NULL, 0, "Process ID", HFILL }},
16725
16726         { &hf_smb_pid_high,
16727                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16728                 NULL, 0, "Process ID High Bytes", HFILL }},
16729
16730         { &hf_smb_tid,
16731                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16732                 NULL, 0, "Tree ID", HFILL }},
16733
16734         { &hf_smb_uid,
16735                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16736                 NULL, 0, "User ID", HFILL }},
16737
16738         { &hf_smb_mid,
16739                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16740                 NULL, 0, "Multiplex ID", HFILL }},
16741
16742         { &hf_smb_flags_lock,
16743                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16744                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16745
16746         { &hf_smb_flags_receive_buffer,
16747                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16748                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16749
16750         { &hf_smb_flags_caseless,
16751                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16752                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16753
16754         { &hf_smb_flags_canon,
16755                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16756                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16757
16758         { &hf_smb_flags_oplock,
16759                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16760                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16761
16762         { &hf_smb_flags_notify,
16763                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16764                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16765
16766         { &hf_smb_flags_response,
16767                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16768                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16769
16770         { &hf_smb_flags2_long_names_allowed,
16771                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16772                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16773
16774         { &hf_smb_flags2_ea,
16775                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16776                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16777
16778         { &hf_smb_flags2_sec_sig,
16779                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16780                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16781
16782         { &hf_smb_flags2_long_names_used,
16783                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16784                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16785
16786         { &hf_smb_flags2_esn,
16787                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16788                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16789
16790         { &hf_smb_flags2_dfs,
16791                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16792                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16793
16794         { &hf_smb_flags2_roe,
16795                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16796                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16797
16798         { &hf_smb_flags2_nt_error,
16799                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16800                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16801
16802         { &hf_smb_flags2_string,
16803                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16804                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16805
16806         { &hf_smb_buffer_format,
16807                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16808                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16809
16810         { &hf_smb_dialect_name,
16811                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16812                 NULL, 0, "Name of dialect", HFILL }},
16813
16814         { &hf_smb_dialect_index,
16815                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16816                 NULL, 0, "Index of selected dialect", HFILL }},
16817
16818         { &hf_smb_max_trans_buf_size,
16819                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16820                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16821
16822         { &hf_smb_max_mpx_count,
16823                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16824                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16825
16826         { &hf_smb_max_vcs_num,
16827                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16828                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16829
16830         { &hf_smb_session_key,
16831                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16832                 NULL, 0, "Unique token identifying this session", HFILL }},
16833
16834         { &hf_smb_server_timezone,
16835                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16836                 NULL, 0, "Current timezone at server.", HFILL }},
16837
16838         { &hf_smb_encryption_key_length,
16839                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16840                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16841
16842         { &hf_smb_encryption_key,
16843                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16844                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16845
16846         { &hf_smb_primary_domain,
16847                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16848                 NULL, 0, "The server's primary domain", HFILL }},
16849
16850         { &hf_smb_server,
16851                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16852                 NULL, 0, "The name of the DC/server", HFILL }},
16853
16854         { &hf_smb_max_raw_buf_size,
16855                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16856                 NULL, 0, "Maximum raw buffer size", HFILL }},
16857
16858         { &hf_smb_server_guid,
16859                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16860                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16861
16862         { &hf_smb_security_blob_len,
16863                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16864                 NULL, 0, "Security blob length", HFILL }},
16865
16866         { &hf_smb_security_blob,
16867                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16868                 NULL, 0, "Security blob", HFILL }},
16869
16870         { &hf_smb_sm_mode16,
16871                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16872                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16873
16874         { &hf_smb_sm_password16,
16875                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16876                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16877
16878         { &hf_smb_sm_mode,
16879                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16880                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16881
16882         { &hf_smb_sm_password,
16883                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16884                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16885
16886         { &hf_smb_sm_signatures,
16887                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16888                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16889
16890         { &hf_smb_sm_sig_required,
16891                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16892                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16893
16894         { &hf_smb_rm_read,
16895                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16896                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16897
16898         { &hf_smb_rm_write,
16899                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16900                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16901
16902         { &hf_smb_server_date_time,
16903                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16904                 NULL, 0, "Current date and time at server", HFILL }},
16905
16906         { &hf_smb_server_smb_date,
16907                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16908                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16909
16910         { &hf_smb_server_smb_time,
16911                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16912                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16913
16914         { &hf_smb_server_cap_raw_mode,
16915                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16916                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16917
16918         { &hf_smb_server_cap_mpx_mode,
16919                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16920                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16921
16922         { &hf_smb_server_cap_unicode,
16923                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16924                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16925
16926         { &hf_smb_server_cap_large_files,
16927                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16928                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16929
16930         { &hf_smb_server_cap_nt_smbs,
16931                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16932                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16933
16934         { &hf_smb_server_cap_rpc_remote_apis,
16935                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16936                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16937
16938         { &hf_smb_server_cap_nt_status,
16939                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16940                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16941
16942         { &hf_smb_server_cap_level_ii_oplocks,
16943                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16944                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16945
16946         { &hf_smb_server_cap_lock_and_read,
16947                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16948                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16949
16950         { &hf_smb_server_cap_nt_find,
16951                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16952                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16953
16954         { &hf_smb_server_cap_dfs,
16955                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16956                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16957
16958         { &hf_smb_server_cap_infolevel_passthru,
16959                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16960                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16961
16962         { &hf_smb_server_cap_large_readx,
16963                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16964                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16965
16966         { &hf_smb_server_cap_large_writex,
16967                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16968                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16969
16970         { &hf_smb_server_cap_unix,
16971                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16972                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16973
16974         { &hf_smb_server_cap_reserved,
16975                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16976                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16977
16978         { &hf_smb_server_cap_bulk_transfer,
16979                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16980                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16981
16982         { &hf_smb_server_cap_compressed_data,
16983                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16984                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16985
16986         { &hf_smb_server_cap_extended_security,
16987                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16988                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16989
16990         { &hf_smb_system_time,
16991                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16992                 NULL, 0, "System Time", HFILL }},
16993
16994         { &hf_smb_unknown,
16995                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16996                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16997
16998         { &hf_smb_dir_name,
16999                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17000                 NULL, 0, "SMB Directory Name", HFILL }},
17001
17002         { &hf_smb_echo_count,
17003                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17004                 NULL, 0, "Number of times to echo data back", HFILL }},
17005
17006         { &hf_smb_echo_data,
17007                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17008                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17009
17010         { &hf_smb_echo_seq_num,
17011                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17012                 NULL, 0, "Sequence number for this echo response", HFILL }},
17013
17014         { &hf_smb_max_buf_size,
17015                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17016                 NULL, 0, "Max client buffer size", HFILL }},
17017
17018         { &hf_smb_path,
17019                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17020                 NULL, 0, "Path. Server name and share name", HFILL }},
17021
17022         { &hf_smb_service,
17023                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17024                 NULL, 0, "Service name", HFILL }},
17025
17026         { &hf_smb_password,
17027                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17028                 NULL, 0, "Password", HFILL }},
17029
17030         { &hf_smb_ansi_password,
17031                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17032                 NULL, 0, "ANSI Password", HFILL }},
17033
17034         { &hf_smb_unicode_password,
17035                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17036                 NULL, 0, "Unicode Password", HFILL }},
17037
17038         { &hf_smb_move_flags_file,
17039                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17040                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17041
17042         { &hf_smb_move_flags_dir,
17043                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17044                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17045
17046         { &hf_smb_move_flags_verify,
17047                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17048                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17049
17050         { &hf_smb_files_moved,
17051                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17052                 NULL, 0, "Number of files moved", HFILL }},
17053
17054         { &hf_smb_copy_flags_file,
17055                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17056                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17057
17058         { &hf_smb_copy_flags_dir,
17059                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17060                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17061
17062         { &hf_smb_copy_flags_dest_mode,
17063                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17064                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17065
17066         { &hf_smb_copy_flags_source_mode,
17067                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17068                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17069
17070         { &hf_smb_copy_flags_verify,
17071                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17072                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17073
17074         { &hf_smb_copy_flags_tree_copy,
17075                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17076                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17077
17078         { &hf_smb_copy_flags_ea_action,
17079                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17080                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17081
17082         { &hf_smb_count,
17083                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17084                 NULL, 0, "Count number of items/bytes", HFILL }},
17085
17086         { &hf_smb_file_name,
17087                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17088                 NULL, 0, "File Name", HFILL }},
17089
17090         { &hf_smb_open_function_create,
17091                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17092                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17093
17094         { &hf_smb_open_function_open,
17095                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17096                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17097
17098         { &hf_smb_fid,
17099                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17100                 NULL, 0, "FID: File ID", HFILL }},
17101
17102         { &hf_smb_file_attr_read_only_16bit,
17103                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17104                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17105
17106         { &hf_smb_file_attr_read_only_8bit,
17107                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17108                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17109
17110         { &hf_smb_file_attr_hidden_16bit,
17111                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17112                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17113
17114         { &hf_smb_file_attr_hidden_8bit,
17115                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17116                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17117
17118         { &hf_smb_file_attr_system_16bit,
17119                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17120                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17121
17122         { &hf_smb_file_attr_system_8bit,
17123                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17124                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17125
17126         { &hf_smb_file_attr_volume_16bit,
17127                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17128                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17129
17130         { &hf_smb_file_attr_volume_8bit,
17131                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17132                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17133
17134         { &hf_smb_file_attr_directory_16bit,
17135                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17136                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17137
17138         { &hf_smb_file_attr_directory_8bit,
17139                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17140                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17141
17142         { &hf_smb_file_attr_archive_16bit,
17143                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17144                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17145
17146         { &hf_smb_file_attr_archive_8bit,
17147                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17148                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17149
17150         { &hf_smb_file_attr_device,
17151                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17152                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17153
17154         { &hf_smb_file_attr_normal,
17155                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17156                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17157
17158         { &hf_smb_file_attr_temporary,
17159                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17160                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17161
17162         { &hf_smb_file_attr_sparse,
17163                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17164                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17165
17166         { &hf_smb_file_attr_reparse,
17167                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17168                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17169
17170         { &hf_smb_file_attr_compressed,
17171                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17172                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17173
17174         { &hf_smb_file_attr_offline,
17175                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17176                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17177
17178         { &hf_smb_file_attr_not_content_indexed,
17179                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17180                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17181
17182         { &hf_smb_file_attr_encrypted,
17183                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17184                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17185
17186         { &hf_smb_file_size,
17187                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17188                 NULL, 0, "File Size", HFILL }},
17189
17190         { &hf_smb_search_attribute_read_only,
17191                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17192                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17193
17194         { &hf_smb_search_attribute_hidden,
17195                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17196                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17197
17198         { &hf_smb_search_attribute_system,
17199                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17200                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17201
17202         { &hf_smb_search_attribute_volume,
17203                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17204                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17205
17206         { &hf_smb_search_attribute_directory,
17207                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17208                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17209
17210         { &hf_smb_search_attribute_archive,
17211                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17212                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17213
17214         { &hf_smb_access_mode,
17215                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17216                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17217
17218         { &hf_smb_access_sharing,
17219                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17220                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17221
17222         { &hf_smb_access_locality,
17223                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17224                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17225
17226         { &hf_smb_access_caching,
17227                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17228                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17229
17230         { &hf_smb_access_writetru,
17231                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17232                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17233
17234         { &hf_smb_create_time,
17235                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17236                 NULL, 0, "Creation Time", HFILL }},
17237
17238         { &hf_smb_modify_time,
17239                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17240                   NULL, 0, "Modification Time", HFILL }},
17241
17242         { &hf_smb_backup_time,
17243                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17244                   NULL, 0, "Backup time", HFILL}},
17245
17246         { &hf_smb_mac_alloc_block_count,
17247                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17248                   NULL, 0, "Allocation Block Count", HFILL}},
17249
17250         { &hf_smb_mac_alloc_block_size,
17251                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17252                   NULL, 0, "Allocation Block Size", HFILL}},
17253
17254         { &hf_smb_mac_free_block_count,
17255                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17256                   NULL, 0, "Free Block Count", HFILL}},
17257
17258         { &hf_smb_mac_root_file_count,
17259                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17260                 NULL, 0, "Root File Count", HFILL}},
17261
17262         { &hf_smb_mac_root_dir_count,
17263           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17264             NULL, 0, "Root Directory Count", HFILL}},
17265
17266         { &hf_smb_mac_file_count,
17267           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17268             NULL, 0, "File Count", HFILL}},
17269
17270         { &hf_smb_mac_dir_count,
17271           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17272             NULL, 0, "Directory Count", HFILL}},
17273
17274         { &hf_smb_mac_support_flags,
17275           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17276             NULL, 0, "Mac Support Flags", HFILL}},
17277
17278         { &hf_smb_mac_sup_access_ctrl,
17279           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17280             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17281
17282         { &hf_smb_mac_sup_getset_comments,
17283           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17284             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17285
17286         { &hf_smb_mac_sup_desktopdb_calls,
17287           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17288             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17289
17290         { &hf_smb_mac_sup_unique_ids,
17291           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17292             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17293
17294         { &hf_smb_mac_sup_streams,
17295           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17296             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17297
17298         { &hf_smb_create_dos_date,
17299                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17300                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17301
17302         { &hf_smb_create_dos_time,
17303                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17304                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17305
17306         { &hf_smb_last_write_time,
17307                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17308                 NULL, 0, "Time this file was last written to", HFILL }},
17309
17310         { &hf_smb_last_write_dos_date,
17311                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17312                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17313
17314         { &hf_smb_last_write_dos_time,
17315                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17316                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17317
17318         { &hf_smb_old_file_name,
17319                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17320                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17321
17322         { &hf_smb_offset,
17323                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17324                 NULL, 0, "Offset in file", HFILL }},
17325
17326         { &hf_smb_remaining,
17327                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17328                 NULL, 0, "Remaining number of bytes", HFILL }},
17329
17330         { &hf_smb_padding,
17331                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17332                 NULL, 0, "Padding or unknown data", HFILL }},
17333
17334         { &hf_smb_file_data,
17335                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17336                 NULL, 0, "Data read/written to the file", HFILL }},
17337
17338         { &hf_smb_mac_fndrinfo,
17339                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17340                   NULL, 0, "Finder Info", HFILL}},
17341
17342         { &hf_smb_total_data_len,
17343                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17344                 NULL, 0, "Total length of data", HFILL }},
17345
17346         { &hf_smb_data_len,
17347                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17348                 NULL, 0, "Length of data", HFILL }},
17349
17350         { &hf_smb_seek_mode,
17351                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17352                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17353
17354         { &hf_smb_access_time,
17355                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17356                 NULL, 0, "Last Access Time", HFILL }},
17357
17358         { &hf_smb_access_dos_date,
17359                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17360                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17361
17362         { &hf_smb_access_dos_time,
17363                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17364                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17365
17366         { &hf_smb_data_size,
17367                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17368                 NULL, 0, "Data Size", HFILL }},
17369
17370         { &hf_smb_alloc_size,
17371                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17372                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17373
17374         { &hf_smb_max_count,
17375                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17376                 NULL, 0, "Maximum Count", HFILL }},
17377
17378         { &hf_smb_min_count,
17379                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17380                 NULL, 0, "Minimum Count", HFILL }},
17381
17382         { &hf_smb_timeout,
17383                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17384                 NULL, 0, "Timeout in miliseconds", HFILL }},
17385
17386         { &hf_smb_high_offset,
17387                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17388                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17389
17390         { &hf_smb_units,
17391                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17392                 NULL, 0, "Total number of units at server", HFILL }},
17393
17394         { &hf_smb_bpu,
17395                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17396                 NULL, 0, "Blocks per unit at server", HFILL }},
17397
17398         { &hf_smb_blocksize,
17399                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17400                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17401
17402         { &hf_smb_freeunits,
17403                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17404                 NULL, 0, "Number of free units at server", HFILL }},
17405
17406         { &hf_smb_data_offset,
17407                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17408                 NULL, 0, "Data Offset", HFILL }},
17409
17410         { &hf_smb_dcm,
17411                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17412                 NULL, 0, "Data Compaction Mode", HFILL }},
17413
17414         { &hf_smb_request_mask,
17415                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17416                 NULL, 0, "Connectionless mode mask", HFILL }},
17417
17418         { &hf_smb_response_mask,
17419                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17420                 NULL, 0, "Connectionless mode mask", HFILL }},
17421
17422         { &hf_smb_search_id,
17423                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17424                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17425
17426         { &hf_smb_write_mode_write_through,
17427                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17428                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17429
17430         { &hf_smb_write_mode_return_remaining,
17431                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17432                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17433
17434         { &hf_smb_write_mode_raw,
17435                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17436                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17437
17438         { &hf_smb_write_mode_message_start,
17439                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17440                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17441
17442         { &hf_smb_write_mode_connectionless,
17443                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17444                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17445
17446         { &hf_smb_resume_key_len,
17447                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17448                 NULL, 0, "Resume Key length", HFILL }},
17449
17450         { &hf_smb_resume_find_id,
17451                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17452                 NULL, 0, "Handle for Find operation", HFILL }},
17453
17454         { &hf_smb_resume_server_cookie,
17455                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17456                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17457
17458         { &hf_smb_resume_client_cookie,
17459                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17460                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17461
17462         { &hf_smb_andxoffset,
17463                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17464                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17465
17466         { &hf_smb_lock_type_large,
17467                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17468                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17469
17470         { &hf_smb_lock_type_cancel,
17471                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17472                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17473
17474         { &hf_smb_lock_type_change,
17475                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17476                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17477
17478         { &hf_smb_lock_type_oplock,
17479                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17480                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17481
17482         { &hf_smb_lock_type_shared,
17483                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17484                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17485
17486         { &hf_smb_locking_ol,
17487                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17488                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17489
17490         { &hf_smb_number_of_locks,
17491                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17492                 NULL, 0, "Number of lock requests in this request", HFILL }},
17493
17494         { &hf_smb_number_of_unlocks,
17495                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17496                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17497
17498         { &hf_smb_lock_long_length,
17499                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17500                 NULL, 0, "Length of lock/unlock region", HFILL }},
17501
17502         { &hf_smb_lock_long_offset,
17503                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17504                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17505
17506         { &hf_smb_file_type,
17507                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17508                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17509
17510         { &hf_smb_ipc_state_nonblocking,
17511                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17512                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17513
17514         { &hf_smb_ipc_state_endpoint,
17515                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17516                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17517
17518         { &hf_smb_ipc_state_pipe_type,
17519                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17520                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17521
17522         { &hf_smb_ipc_state_read_mode,
17523                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17524                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17525
17526         { &hf_smb_ipc_state_icount,
17527                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17528                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17529
17530         { &hf_smb_server_fid,
17531                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17532                 NULL, 0, "Server unique File ID", HFILL }},
17533
17534         { &hf_smb_open_flags_add_info,
17535                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17536                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17537
17538         { &hf_smb_open_flags_ex_oplock,
17539                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17540                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17541
17542         { &hf_smb_open_flags_batch_oplock,
17543                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17544                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17545
17546         { &hf_smb_open_flags_ealen,
17547                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17548                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17549
17550         { &hf_smb_open_action_open,
17551                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17552                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17553
17554         { &hf_smb_open_action_lock,
17555                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17556                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17557
17558         { &hf_smb_vc_num,
17559                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17560                 NULL, 0, "VC Number", HFILL }},
17561
17562         { &hf_smb_password_len,
17563                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17564                 NULL, 0, "Length of password", HFILL }},
17565
17566         { &hf_smb_ansi_password_len,
17567                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17568                 NULL, 0, "Length of ANSI password", HFILL }},
17569
17570         { &hf_smb_unicode_password_len,
17571                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17572                 NULL, 0, "Length of Unicode password", HFILL }},
17573
17574         { &hf_smb_account,
17575                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17576                 NULL, 0, "Account, username", HFILL }},
17577
17578         { &hf_smb_os,
17579                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17580                 NULL, 0, "Which OS we are running", HFILL }},
17581
17582         { &hf_smb_lanman,
17583                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17584                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17585
17586         { &hf_smb_setup_action_guest,
17587                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17588                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17589
17590         { &hf_smb_fs,
17591                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17592                 NULL, 0, "Native File System", HFILL }},
17593
17594         { &hf_smb_connect_flags_dtid,
17595                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17596                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17597
17598         { &hf_smb_connect_support_search,
17599                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17600                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17601
17602         { &hf_smb_connect_support_in_dfs,
17603                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17604                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17605
17606         { &hf_smb_max_setup_count,
17607                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17608                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17609
17610         { &hf_smb_total_param_count,
17611                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17612                 NULL, 0, "Total number of parameter bytes", HFILL }},
17613
17614         { &hf_smb_total_data_count,
17615                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17616                 NULL, 0, "Total number of data bytes", HFILL }},
17617
17618         { &hf_smb_max_param_count,
17619                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17620                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17621
17622         { &hf_smb_max_data_count,
17623                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17624                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17625
17626         { &hf_smb_param_disp16,
17627                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17628                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17629
17630         { &hf_smb_param_count16,
17631                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17632                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17633
17634         { &hf_smb_param_offset16,
17635                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17636                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17637
17638         { &hf_smb_param_disp32,
17639                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17640                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17641
17642         { &hf_smb_param_count32,
17643                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17644                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17645
17646         { &hf_smb_param_offset32,
17647                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17648                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17649
17650         { &hf_smb_data_count16,
17651                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17652                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17653
17654         { &hf_smb_data_disp16,
17655                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17656                 NULL, 0, "Data Displacement", HFILL }},
17657
17658         { &hf_smb_data_offset16,
17659                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17660                 NULL, 0, "Data Offset", HFILL }},
17661
17662         { &hf_smb_data_count32,
17663                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17664                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17665
17666         { &hf_smb_data_disp32,
17667                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17668                 NULL, 0, "Data Displacement", HFILL }},
17669
17670         { &hf_smb_data_offset32,
17671                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17672                 NULL, 0, "Data Offset", HFILL }},
17673
17674         { &hf_smb_setup_count,
17675                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17676                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17677
17678         { &hf_smb_nt_trans_subcmd,
17679                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17680                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17681
17682         { &hf_smb_nt_ioctl_function_code,
17683                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17684                 NULL, 0, "NT IOCTL function code", HFILL }},
17685
17686         { &hf_smb_nt_ioctl_isfsctl,
17687                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17688                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17689
17690         { &hf_smb_nt_ioctl_flags_root_handle,
17691                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17692                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17693
17694         { &hf_smb_nt_ioctl_data,
17695                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17696                 NULL, 0, "Data for the IOCTL call", HFILL }},
17697
17698         { &hf_smb_nt_notify_action,
17699                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17700                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17701
17702         { &hf_smb_nt_notify_watch_tree,
17703                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17704                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17705
17706         { &hf_smb_nt_notify_stream_write,
17707                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17708                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17709
17710         { &hf_smb_nt_notify_stream_size,
17711                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17712                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17713
17714         { &hf_smb_nt_notify_stream_name,
17715                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17716                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17717
17718         { &hf_smb_nt_notify_security,
17719                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17720                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17721
17722         { &hf_smb_nt_notify_ea,
17723                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17724                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17725
17726         { &hf_smb_nt_notify_creation,
17727                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17728                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17729
17730         { &hf_smb_nt_notify_last_access,
17731                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17732                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17733
17734         { &hf_smb_nt_notify_last_write,
17735                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17736                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17737
17738         { &hf_smb_nt_notify_size,
17739                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17740                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17741
17742         { &hf_smb_nt_notify_attributes,
17743                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17744                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17745
17746         { &hf_smb_nt_notify_dir_name,
17747                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17748                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17749
17750         { &hf_smb_nt_notify_file_name,
17751                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17752                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17753
17754         { &hf_smb_root_dir_fid,
17755                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17756                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17757
17758         { &hf_smb_alloc_size64,
17759                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17760                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17761
17762         { &hf_smb_nt_create_disposition,
17763                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17764                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17765
17766         { &hf_smb_sd_length,
17767                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17768                 NULL, 0, "Total length of security descriptor", HFILL }},
17769
17770         { &hf_smb_ea_list_length,
17771                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17772                 NULL, 0, "Total length of extended attributes", HFILL }},
17773
17774         { &hf_smb_ea_flags,
17775                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17776                 NULL, 0, "EA Flags", HFILL }},
17777
17778         { &hf_smb_ea_name_length,
17779                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17780                 NULL, 0, "EA Name Length", HFILL }},
17781
17782         { &hf_smb_ea_data_length,
17783                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17784                 NULL, 0, "EA Data Length", HFILL }},
17785
17786         { &hf_smb_ea_name,
17787                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17788                 NULL, 0, "EA Name", HFILL }},
17789
17790         { &hf_smb_ea_data,
17791                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17792                 NULL, 0, "EA Data", HFILL }},
17793
17794         { &hf_smb_file_name_len,
17795                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17796                 NULL, 0, "Length of File Name", HFILL }},
17797
17798         { &hf_smb_nt_impersonation_level,
17799                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17800                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17801
17802         { &hf_smb_nt_security_flags_context_tracking,
17803                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17804                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17805
17806         { &hf_smb_nt_security_flags_effective_only,
17807                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17808                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17809
17810         { &hf_smb_nt_access_mask_generic_read,
17811                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17812                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17813
17814         { &hf_smb_nt_access_mask_generic_write,
17815                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17816                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17817
17818         { &hf_smb_nt_access_mask_generic_execute,
17819                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17820                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17821
17822         { &hf_smb_nt_access_mask_generic_all,
17823                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17824                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17825
17826         { &hf_smb_nt_access_mask_maximum_allowed,
17827                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17828                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17829
17830         { &hf_smb_nt_access_mask_system_security,
17831                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17832                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17833
17834         { &hf_smb_nt_access_mask_synchronize,
17835                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17836                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17837
17838         { &hf_smb_nt_access_mask_write_owner,
17839                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17840                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17841
17842         { &hf_smb_nt_access_mask_write_dac,
17843                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17844                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17845
17846         { &hf_smb_nt_access_mask_read_control,
17847                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17848                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17849
17850         { &hf_smb_nt_access_mask_delete,
17851                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17852                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17853
17854         { &hf_smb_nt_access_mask_write_attributes,
17855                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17856                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17857
17858         { &hf_smb_nt_access_mask_read_attributes,
17859                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17860                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17861
17862         { &hf_smb_nt_access_mask_delete_child,
17863                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17864                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17865
17866         /*
17867          * "Execute" for files, "traverse" for directories.
17868          */
17869         { &hf_smb_nt_access_mask_execute,
17870                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17871                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17872
17873         { &hf_smb_nt_access_mask_write_ea,
17874                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17875                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17876
17877         { &hf_smb_nt_access_mask_read_ea,
17878                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17879                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17880
17881         /*
17882          * "Append data" for files, "add subdirectory" for directories,
17883          * "create pipe instance" for named pipes.
17884          */
17885         { &hf_smb_nt_access_mask_append,
17886                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17887                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17888
17889         /*
17890          * "Write data" for files and pipes, "add file" for directory.
17891          */
17892         { &hf_smb_nt_access_mask_write,
17893                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17894                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17895
17896         /*
17897          * "Read data" for files and pipes, "list directory" for directory.
17898          */
17899         { &hf_smb_nt_access_mask_read,
17900                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17901                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17902
17903         { &hf_smb_nt_create_bits_oplock,
17904                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17905                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17906
17907         { &hf_smb_nt_create_bits_boplock,
17908                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17909                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17910
17911         { &hf_smb_nt_create_bits_dir,
17912                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17913                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17914
17915         { &hf_smb_nt_create_bits_ext_resp,
17916           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
17917             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
17918
17919         { &hf_smb_nt_create_options_directory_file,
17920                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17921                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17922
17923         { &hf_smb_nt_create_options_write_through,
17924                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17925                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17926
17927         { &hf_smb_nt_create_options_sequential_only,
17928                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17929                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17930
17931         { &hf_smb_nt_create_options_sync_io_alert,
17932                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17933                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17934
17935         { &hf_smb_nt_create_options_sync_io_nonalert,
17936                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17937                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17938
17939         { &hf_smb_nt_create_options_non_directory_file,
17940                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17941                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17942
17943         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
17944            and "NtOpenFile()"; is that sent over the wire?  Network
17945            Monitor thinks so, but its author may just have grabbed
17946            the flag bits from a system header file. */
17947
17948         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
17949            and "NtOpenFile()"; is that sent over the wire?  NetMon
17950            thinks so, but see previous comment. */
17951
17952         { &hf_smb_nt_create_options_no_ea_knowledge,
17953                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17954                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17955
17956         { &hf_smb_nt_create_options_eight_dot_three_only,
17957                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17958                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17959
17960         { &hf_smb_nt_create_options_random_access,
17961                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17962                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17963
17964         { &hf_smb_nt_create_options_delete_on_close,
17965                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17966                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17967
17968         /* 0x00002000 is "open by FID", or something such as that (which
17969            I suspect is like "open by inumber" on UNIX), at least in
17970            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
17971            wire?  NetMon thinks so, but see previous comment. */
17972
17973         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
17974            and "NtOpenFile()"; is that sent over the wire?  NetMon
17975            thinks so, but see previous comment. */
17976
17977         { &hf_smb_nt_share_access_read,
17978                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17979                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
17980
17981         { &hf_smb_nt_share_access_write,
17982                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17983                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
17984
17985         { &hf_smb_nt_share_access_delete,
17986                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17987                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
17988
17989         { &hf_smb_file_eattr_read_only,
17990                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17991                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17992
17993         { &hf_smb_file_eattr_hidden,
17994                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17995                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17996
17997         { &hf_smb_file_eattr_system,
17998                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17999                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18000
18001         { &hf_smb_file_eattr_volume,
18002                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18003                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18004
18005         { &hf_smb_file_eattr_directory,
18006                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18007                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18008
18009         { &hf_smb_file_eattr_archive,
18010                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18011                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18012
18013         { &hf_smb_file_eattr_device,
18014                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18015                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18016
18017         { &hf_smb_file_eattr_normal,
18018                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18019                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18020
18021         { &hf_smb_file_eattr_temporary,
18022                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18023                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18024
18025         { &hf_smb_file_eattr_sparse,
18026                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18027                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18028
18029         { &hf_smb_file_eattr_reparse,
18030                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18031                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18032
18033         { &hf_smb_file_eattr_compressed,
18034                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18035                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18036
18037         { &hf_smb_file_eattr_offline,
18038                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18039                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18040
18041         { &hf_smb_file_eattr_not_content_indexed,
18042                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18043                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18044
18045         { &hf_smb_file_eattr_encrypted,
18046                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18047                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18048
18049         { &hf_smb_sec_desc_len,
18050                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18051                 NULL, 0, "Security Descriptor Length", HFILL }},
18052
18053         { &hf_smb_nt_qsd_owner,
18054                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18055                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18056
18057         { &hf_smb_nt_qsd_group,
18058                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18059                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18060
18061         { &hf_smb_nt_qsd_dacl,
18062                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18063                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18064
18065         { &hf_smb_nt_qsd_sacl,
18066                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18067                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18068
18069         { &hf_smb_extended_attributes,
18070                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18071                 NULL, 0, "Extended Attributes", HFILL }},
18072
18073         { &hf_smb_oplock_level,
18074                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18075                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18076
18077         { &hf_smb_create_action,
18078                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18079                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18080
18081         { &hf_smb_file_id,
18082                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18083                 NULL, 0, "Server unique file ID", HFILL }},
18084
18085         { &hf_smb_ea_error_offset,
18086                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18087                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18088
18089         { &hf_smb_end_of_file,
18090                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18091                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18092
18093         { &hf_smb_device_type,
18094                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18095                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18096
18097         { &hf_smb_is_directory,
18098                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18099                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18100
18101         { &hf_smb_next_entry_offset,
18102                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18103                 NULL, 0, "Offset to next entry", HFILL }},
18104
18105         { &hf_smb_change_time,
18106                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18107                 NULL, 0, "Last Change Time", HFILL }},
18108
18109         { &hf_smb_setup_len,
18110                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18111                 NULL, 0, "Length of printer setup data", HFILL }},
18112
18113         { &hf_smb_print_mode,
18114                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18115                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18116
18117         { &hf_smb_print_identifier,
18118                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18119                 NULL, 0, "Identifier string for this print job", HFILL }},
18120
18121         { &hf_smb_restart_index,
18122                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18123                 NULL, 0, "Index of entry after last returned", HFILL }},
18124
18125         { &hf_smb_print_queue_date,
18126                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18127                 NULL, 0, "Date when this entry was queued", HFILL }},
18128
18129         { &hf_smb_print_queue_dos_date,
18130                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18131                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18132
18133         { &hf_smb_print_queue_dos_time,
18134                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18135                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18136
18137         { &hf_smb_print_status,
18138                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18139                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18140
18141         { &hf_smb_print_spool_file_number,
18142                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18143                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18144
18145         { &hf_smb_print_spool_file_size,
18146                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18147                 NULL, 0, "Number of bytes in spool file", HFILL }},
18148
18149         { &hf_smb_print_spool_file_name,
18150                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18151                 NULL, 0, "Name of client that submitted this job", HFILL }},
18152
18153         { &hf_smb_start_index,
18154                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18155                 NULL, 0, "First queue entry to return", HFILL }},
18156
18157         { &hf_smb_originator_name,
18158                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18159                 NULL, 0, "Name of sender of message", HFILL }},
18160
18161         { &hf_smb_destination_name,
18162                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18163                 NULL, 0, "Name of recipient of message", HFILL }},
18164
18165         { &hf_smb_message_len,
18166                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18167                 NULL, 0, "Length of message", HFILL }},
18168
18169         { &hf_smb_message,
18170                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18171                 NULL, 0, "Message text", HFILL }},
18172
18173         { &hf_smb_mgid,
18174                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18175                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18176
18177         { &hf_smb_forwarded_name,
18178                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18179                 NULL, 0, "Recipient name being forwarded", HFILL }},
18180
18181         { &hf_smb_machine_name,
18182                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18183                 NULL, 0, "Name of target machine", HFILL }},
18184
18185         { &hf_smb_cancel_to,
18186                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18187                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18188
18189         { &hf_smb_trans2_subcmd,
18190                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18191                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18192
18193         { &hf_smb_trans_name,
18194                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18195                 NULL, 0, "Name of transaction", HFILL }},
18196
18197         { &hf_smb_transaction_flags_dtid,
18198                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18199                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18200
18201         { &hf_smb_transaction_flags_owt,
18202                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18203                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18204
18205         { &hf_smb_search_count,
18206                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18207                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18208
18209         { &hf_smb_search_pattern,
18210                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18211                 NULL, 0, "Search Pattern", HFILL }},
18212
18213         { &hf_smb_ff2_backup,
18214                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18215                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18216
18217         { &hf_smb_ff2_continue,
18218                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18219                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18220
18221         { &hf_smb_ff2_resume,
18222                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18223                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18224
18225         { &hf_smb_ff2_close_eos,
18226                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18227                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18228
18229         { &hf_smb_ff2_close,
18230                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18231                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18232
18233         { &hf_smb_ff2_information_level,
18234                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18235                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18236
18237         { &hf_smb_qpi_loi,
18238                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18239                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18240
18241         { &hf_smb_spi_loi,
18242                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18243                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18244
18245 #if 0
18246         { &hf_smb_sfi_writetru,
18247                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18248                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18249
18250         { &hf_smb_sfi_caching,
18251                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18252                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18253 #endif
18254
18255         { &hf_smb_storage_type,
18256                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18257                 NULL, 0, "Type of storage", HFILL }},
18258
18259         { &hf_smb_resume,
18260                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18261                 NULL, 0, "Resume Key", HFILL }},
18262
18263         { &hf_smb_max_referral_level,
18264                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18265                 NULL, 0, "Latest referral version number understood", HFILL }},
18266
18267         { &hf_smb_qfsi_information_level,
18268                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18269                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18270
18271         { &hf_smb_nt_rename_level,
18272                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18273                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18274
18275         { &hf_smb_cluster_count,
18276                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18277                 NULL, 0, "Number of clusters", HFILL }},
18278
18279         { &hf_smb_number_of_links,
18280                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18281                 NULL, 0, "Number of hard links to the file", HFILL }},
18282
18283         { &hf_smb_delete_pending,
18284                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18285                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18286
18287         { &hf_smb_index_number,
18288                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18289                 NULL, 0, "File system unique identifier", HFILL }},
18290
18291         { &hf_smb_current_offset,
18292                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18293                 NULL, 0, "Current offset in the file", HFILL }},
18294
18295         { &hf_smb_t2_alignment,
18296                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18297                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18298
18299         { &hf_smb_t2_stream_name_length,
18300                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18301                 NULL, 0, "Length of stream name", HFILL }},
18302
18303         { &hf_smb_t2_stream_size,
18304                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18305                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18306
18307         { &hf_smb_t2_stream_name,
18308                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18309                 NULL, 0, "Name of the stream", HFILL }},
18310
18311         { &hf_smb_t2_compressed_file_size,
18312                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18313                 NULL, 0, "Size of the compressed file", HFILL }},
18314
18315         { &hf_smb_t2_compressed_format,
18316                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18317                 NULL, 0, "Compression algorithm used", HFILL }},
18318
18319         { &hf_smb_t2_compressed_unit_shift,
18320                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18321                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18322
18323         { &hf_smb_t2_compressed_chunk_shift,
18324                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18325                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18326
18327         { &hf_smb_t2_compressed_cluster_shift,
18328                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18329                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18330
18331         { &hf_smb_t2_marked_for_deletion,
18332                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18333                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18334
18335         { &hf_smb_dfs_path_consumed,
18336                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18337                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18338
18339         { &hf_smb_dfs_num_referrals,
18340                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18341                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18342
18343         { &hf_smb_get_dfs_server_hold_storage,
18344                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18345                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18346
18347         { &hf_smb_get_dfs_fielding,
18348                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18349                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18350
18351         { &hf_smb_dfs_referral_version,
18352                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18353                 NULL, 0, "Version of referral element", HFILL }},
18354
18355         { &hf_smb_dfs_referral_size,
18356                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18357                 NULL, 0, "Size of referral element", HFILL }},
18358
18359         { &hf_smb_dfs_referral_server_type,
18360                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18361                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18362
18363         { &hf_smb_dfs_referral_flags_strip,
18364                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18365                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18366
18367         { &hf_smb_dfs_referral_node_offset,
18368                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18369                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18370
18371         { &hf_smb_dfs_referral_node,
18372                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18373                 NULL, 0, "Name of entity to visit next", HFILL }},
18374
18375         { &hf_smb_dfs_referral_proximity,
18376                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18377                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18378
18379         { &hf_smb_dfs_referral_ttl,
18380                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18381                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18382
18383         { &hf_smb_dfs_referral_path_offset,
18384                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18385                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18386
18387         { &hf_smb_dfs_referral_path,
18388                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18389                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18390
18391         { &hf_smb_dfs_referral_alt_path_offset,
18392                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18393                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18394
18395         { &hf_smb_dfs_referral_alt_path,
18396                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18397                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18398
18399         { &hf_smb_end_of_search,
18400                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18401                 NULL, 0, "Was last entry returned?", HFILL }},
18402
18403         { &hf_smb_last_name_offset,
18404                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18405                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18406
18407         { &hf_smb_fn_information_level,
18408                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18409                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18410
18411         { &hf_smb_monitor_handle,
18412                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18413                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18414
18415         { &hf_smb_change_count,
18416                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18417                 NULL, 0, "Number of changes to wait for", HFILL }},
18418
18419         { &hf_smb_file_index,
18420                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18421                 NULL, 0, "File index", HFILL }},
18422
18423         { &hf_smb_short_file_name,
18424                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18425                 NULL, 0, "Short (8.3) File Name", HFILL }},
18426
18427         { &hf_smb_short_file_name_len,
18428                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18429                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18430
18431         { &hf_smb_fs_id,
18432                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18433                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18434
18435         { &hf_smb_sector_unit,
18436                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18437                 NULL, 0, "Sectors per allocation unit", HFILL }},
18438
18439         { &hf_smb_fs_units,
18440                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18441                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18442
18443         { &hf_smb_fs_sector,
18444                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18445                 NULL, 0, "Bytes per sector", HFILL }},
18446
18447         { &hf_smb_avail_units,
18448                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18449                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18450
18451         { &hf_smb_volume_serial_num,
18452                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18453                 NULL, 0, "Volume serial number", HFILL }},
18454
18455         { &hf_smb_volume_label_len,
18456                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18457                 NULL, 0, "Length of volume label", HFILL }},
18458
18459         { &hf_smb_volume_label,
18460                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18461                 NULL, 0, "Volume label", HFILL }},
18462
18463         { &hf_smb_free_alloc_units64,
18464                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18465                 NULL, 0, "Number of free allocation units", HFILL }},
18466
18467         { &hf_smb_caller_free_alloc_units64,
18468                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18469                 NULL, 0, "Number of caller free allocation units", HFILL }},
18470
18471         { &hf_smb_actual_free_alloc_units64,
18472                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18473                 NULL, 0, "Number of actual free allocation units", HFILL }},
18474
18475         { &hf_smb_soft_quota_limit,
18476                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18477                 NULL, 0, "Soft Quota treshold", HFILL }},
18478
18479         { &hf_smb_hard_quota_limit,
18480                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18481                 NULL, 0, "Hard Quota limit", HFILL }},
18482
18483         { &hf_smb_user_quota_used,
18484                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18485                 NULL, 0, "How much Quota is used by this user", HFILL }},
18486
18487         { &hf_smb_max_name_len,
18488                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18489                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18490
18491         { &hf_smb_fs_name_len,
18492                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18493                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18494
18495         { &hf_smb_fs_name,
18496                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18497                 NULL, 0, "Name of filesystem", HFILL }},
18498
18499         { &hf_smb_device_char_removable,
18500                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18501                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18502
18503         { &hf_smb_device_char_read_only,
18504                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18505                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18506
18507         { &hf_smb_device_char_floppy,
18508                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18509                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18510
18511         { &hf_smb_device_char_write_once,
18512                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18513                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18514
18515         { &hf_smb_device_char_remote,
18516                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18517                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18518
18519         { &hf_smb_device_char_mounted,
18520                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18521                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18522
18523         { &hf_smb_device_char_virtual,
18524                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18525                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18526
18527         { &hf_smb_fs_attr_css,
18528                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18529                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18530
18531         { &hf_smb_fs_attr_cpn,
18532                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18533                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18534
18535         { &hf_smb_fs_attr_pacls,
18536                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18537                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18538
18539         { &hf_smb_fs_attr_fc,
18540                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18541                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18542
18543         { &hf_smb_fs_attr_vq,
18544                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18545                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18546
18547         { &hf_smb_fs_attr_dim,
18548                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18549                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18550
18551         { &hf_smb_fs_attr_vic,
18552                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18553                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18554
18555         { &hf_smb_sec_desc_revision,
18556                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18557                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18558
18559         { &hf_smb_sid,
18560                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18561                 NULL, 0, "SID: Security Identifier", HFILL }},
18562
18563         { &hf_smb_sid_revision,
18564                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18565                 NULL, 0, "Version of SID structure", HFILL }},
18566
18567         { &hf_smb_sid_num_auth,
18568                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18569                 NULL, 0, "Number of authorities for this SID", HFILL }},
18570
18571         { &hf_smb_acl_revision,
18572                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18573                 NULL, 0, "Version of NT ACL structure", HFILL }},
18574
18575         { &hf_smb_acl_size,
18576                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18577                 NULL, 0, "Size of NT ACL structure", HFILL }},
18578
18579         { &hf_smb_acl_num_aces,
18580                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18581                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18582
18583         { &hf_smb_user_quota_offset,
18584                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18585                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18586
18587         { &hf_smb_ace_type,
18588                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18589                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18590
18591         { &hf_smb_pipe_write_len,
18592                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18593                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18594
18595         { &hf_smb_ace_size,
18596                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18597                 NULL, 0, "Size of this ACE", HFILL }},
18598
18599         { &hf_smb_ace_flags_object_inherit,
18600                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18601                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18602
18603         { &hf_smb_ace_flags_container_inherit,
18604                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18605                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18606
18607         { &hf_smb_ace_flags_non_propagate_inherit,
18608                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18609                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18610
18611         { &hf_smb_ace_flags_inherit_only,
18612                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18613                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18614
18615         { &hf_smb_ace_flags_inherited_ace,
18616                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18617                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18618
18619         { &hf_smb_ace_flags_successful_access,
18620                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18621                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18622
18623         { &hf_smb_ace_flags_failed_access,
18624                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18625                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18626
18627         { &hf_smb_sec_desc_type_owner_defaulted,
18628                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18629                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18630
18631         { &hf_smb_sec_desc_type_group_defaulted,
18632                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18633                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18634
18635         { &hf_smb_sec_desc_type_dacl_present,
18636                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18637                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18638
18639         { &hf_smb_sec_desc_type_dacl_defaulted,
18640                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18641                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18642
18643         { &hf_smb_sec_desc_type_sacl_present,
18644                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18645                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18646
18647         { &hf_smb_sec_desc_type_sacl_defaulted,
18648                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18649                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18650
18651         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18652                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18653                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18654
18655         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18656                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18657                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18658
18659         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18660                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18661                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18662
18663         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18664                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18665                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18666
18667         { &hf_smb_sec_desc_type_dacl_protected,
18668                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18669                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18670
18671         { &hf_smb_sec_desc_type_sacl_protected,
18672                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18673                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18674
18675         { &hf_smb_sec_desc_type_self_relative,
18676                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18677                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18678
18679         { &hf_smb_quota_flags_deny_disk,
18680                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18681                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18682
18683         { &hf_smb_quota_flags_log_limit,
18684                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18685                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18686
18687         { &hf_smb_quota_flags_log_warning,
18688                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18689                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18690
18691         { &hf_smb_quota_flags_enabled,
18692                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18693                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18694
18695         { &hf_smb_segment_overlap,
18696                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18697                         "Fragment overlaps with other fragments", HFILL }},
18698
18699         { &hf_smb_segment_overlap_conflict,
18700                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18701                         "Overlapping fragments contained conflicting data", HFILL }},
18702
18703         { &hf_smb_segment_multiple_tails,
18704                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18705                         "Several tails were found when defragmenting the packet", HFILL }},
18706
18707         { &hf_smb_segment_too_long_fragment,
18708                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18709                         "Fragment contained data past end of packet", HFILL }},
18710
18711         { &hf_smb_segment_error,
18712                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18713                         "Defragmentation error due to illegal fragments", HFILL }},
18714
18715         { &hf_smb_segment,
18716                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18717                         "SMB Segment", HFILL }},
18718
18719         { &hf_smb_segments,
18720                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18721                         "SMB Segments", HFILL }},
18722
18723         { &hf_smb_unix_major_version,
18724           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18725             NULL, 0, "UNIX Major Version", HFILL }},
18726
18727         { &hf_smb_unix_minor_version,
18728           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18729             NULL, 0, "UNIX Minor Version", HFILL }},
18730
18731         { &hf_smb_unix_capability_fcntl,
18732           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18733                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18734
18735         { &hf_smb_unix_capability_posix_acl,
18736           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18737                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18738
18739         { &hf_smb_unix_file_size,
18740           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18741             NULL, 0, "", HFILL }},
18742
18743         { &hf_smb_unix_file_num_bytes,
18744           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18745             NULL, 0, "Number of bytes used to store the file", HFILL }},
18746
18747         { &hf_smb_unix_file_last_status,
18748           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18749             NULL, 0, "", HFILL }},
18750
18751         { &hf_smb_unix_file_last_access,
18752           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18753             NULL, 0, "", HFILL }},
18754
18755         { &hf_smb_unix_file_last_change,
18756           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18757             NULL, 0, "", HFILL }},
18758
18759         { &hf_smb_unix_file_uid,
18760           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18761             NULL, 0, "", HFILL }},
18762
18763         { &hf_smb_unix_file_gid,
18764           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18765             NULL, 0, "", HFILL }},
18766
18767         { &hf_smb_unix_file_type,
18768           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18769             VALS(unix_file_type_vals), 0, "", HFILL }},
18770
18771         { &hf_smb_unix_file_dev_major,
18772           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18773             NULL, 0, "", HFILL }},
18774
18775         { &hf_smb_unix_file_dev_minor,
18776           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18777             NULL, 0, "", HFILL }},
18778
18779         { &hf_smb_unix_file_unique_id,
18780           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18781             NULL, 0, "", HFILL }},
18782
18783         { &hf_smb_unix_file_permissions,
18784           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18785             NULL, 0, "", HFILL }},
18786
18787         { &hf_smb_unix_file_nlinks,
18788           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18789             NULL, 0, "", HFILL }},
18790
18791         { &hf_smb_unix_find_file_nextoffset,
18792           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18793             NULL, 0, "", HFILL }},
18794
18795         { &hf_smb_unix_find_file_resumekey,
18796           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18797             NULL, 0, "", HFILL }},
18798
18799                 /* Access masks */
18800
18801                 { &hf_smb_access_mask,
18802                   { "Access required", "smb.access_mask",
18803                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18804                     HFILL }},
18805                 { &hf_access_generic_read,
18806                   { "Generic read", "nt.access_mask.generic_read",
18807                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18808                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18809
18810                 { &hf_access_generic_write,
18811                   { "Generic write", "nt.access_mask.generic_write",
18812                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18813                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
18814
18815                 { &hf_access_generic_execute,
18816                   { "Generic execute", "nt.access_mask.generic_execute",
18817                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18818                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
18819
18820                 { &hf_access_generic_all,
18821                   { "Generic all", "nt.access_mask.generic_all",
18822                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18823                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
18824
18825                 { &hf_access_maximum_allowed,
18826                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
18827                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18828                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
18829
18830                 { &hf_access_sacl,
18831                   { "Access SACL", "nt.access_mask.access_sacl",
18832                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18833                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
18834
18835                 { &hf_access_standard_read_control,
18836                   { "Read control", "nt.access_mask.read_control",
18837                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18838                     READ_CONTROL_ACCESS, "Read control", HFILL }},
18839
18840                 { &hf_access_standard_delete,
18841                   { "Delete", "nt.access_mask.delete",
18842                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18843                     DELETE_ACCESS, "Delete", HFILL }},
18844
18845                 { &hf_access_standard_synchronise,
18846                   { "Synchronise", "nt.access_mask.synchronise",
18847                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18848                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
18849
18850                 { &hf_access_standard_write_dac,
18851                   { "Write DAC", "nt.access_mask.write_dac",
18852                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18853                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
18854
18855                 { &hf_access_standard_write_owner,
18856                   { "Write owner", "nt.access_mask.write_owner",
18857                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18858                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
18859
18860                 { &hf_access_specific_15,
18861                   { "Specific access, bit 15", "nt.access_mask.specific_15",
18862                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18863                     0x8000, "Specific access, bit 15", HFILL }},
18864
18865                 { &hf_access_specific_14,
18866                   { "Specific access, bit 14", "nt.access_mask.specific_14",
18867                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18868                     0x4000, "Specific access, bit 14", HFILL }},
18869
18870                 { &hf_access_specific_13,
18871                   { "Specific access, bit 13", "nt.access_mask.specific_13",
18872                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18873                     0x2000, "Specific access, bit 13", HFILL }},
18874
18875                 { &hf_access_specific_12,
18876                   { "Specific access, bit 12", "nt.access_mask.specific_12",
18877                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18878                     0x1000, "Specific access, bit 12", HFILL }},
18879
18880                 { &hf_access_specific_11,
18881                   { "Specific access, bit 11", "nt.access_mask.specific_11",
18882                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18883                     0x0800, "Specific access, bit 11", HFILL }},
18884
18885                 { &hf_access_specific_10,
18886                   { "Specific access, bit 10", "nt.access_mask.specific_10",
18887                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18888                     0x0400, "Specific access, bit 10", HFILL }},
18889
18890                 { &hf_access_specific_9,
18891                   { "Specific access, bit 9", "nt.access_mask.specific_9",
18892                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18893                     0x0200, "Specific access, bit 9", HFILL }},
18894
18895                 { &hf_access_specific_8,
18896                   { "Specific access, bit 8", "nt.access_mask.specific_8",
18897                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18898                     0x0100, "Specific access, bit 8", HFILL }},
18899
18900                 { &hf_access_specific_7,
18901                   { "Specific access, bit 7", "nt.access_mask.specific_7",
18902                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18903                     0x0080, "Specific access, bit 7", HFILL }},
18904
18905                 { &hf_access_specific_6,
18906                   { "Specific access, bit 6", "nt.access_mask.specific_6",
18907                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18908                     0x0040, "Specific access, bit 6", HFILL }},
18909
18910                 { &hf_access_specific_5,
18911                   { "Specific access, bit 5", "nt.access_mask.specific_5",
18912                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18913                     0x0020, "Specific access, bit 5", HFILL }},
18914
18915                 { &hf_access_specific_4,
18916                   { "Specific access, bit 4", "nt.access_mask.specific_4",
18917                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18918                     0x0010, "Specific access, bit 4", HFILL }},
18919
18920                 { &hf_access_specific_3,
18921                   { "Specific access, bit 3", "nt.access_mask.specific_3",
18922                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18923                     0x0008, "Specific access, bit 3", HFILL }},
18924
18925                 { &hf_access_specific_2,
18926                   { "Specific access, bit 2", "nt.access_mask.specific_2",
18927                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18928                     0x0004, "Specific access, bit 2", HFILL }},
18929
18930                 { &hf_access_specific_1,
18931                   { "Specific access, bit 1", "nt.access_mask.specific_1",
18932                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18933                     0x0002, "Specific access, bit 1", HFILL }},
18934
18935                 { &hf_access_specific_0,
18936                   { "Specific access, bit 0", "nt.access_mask.specific_0",
18937                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18938                     0x0001, "Specific access, bit 0", HFILL }}
18939         };
18940
18941         static gint *ett[] = {
18942                 &ett_smb,
18943                 &ett_smb_hdr,
18944                 &ett_smb_command,
18945                 &ett_smb_fileattributes,
18946                 &ett_smb_capabilities,
18947                 &ett_smb_aflags,
18948                 &ett_smb_dialect,
18949                 &ett_smb_dialects,
18950                 &ett_smb_mode,
18951                 &ett_smb_rawmode,
18952                 &ett_smb_flags,
18953                 &ett_smb_flags2,
18954                 &ett_smb_desiredaccess,
18955                 &ett_smb_search,
18956                 &ett_smb_file,
18957                 &ett_smb_openfunction,
18958                 &ett_smb_filetype,
18959                 &ett_smb_openaction,
18960                 &ett_smb_writemode,
18961                 &ett_smb_lock_type,
18962                 &ett_smb_ssetupandxaction,
18963                 &ett_smb_optionsup,
18964                 &ett_smb_time_date,
18965                 &ett_smb_move_copy_flags,
18966                 &ett_smb_file_attributes,
18967                 &ett_smb_search_resume_key,
18968                 &ett_smb_search_dir_info,
18969                 &ett_smb_unlocks,
18970                 &ett_smb_unlock,
18971                 &ett_smb_locks,
18972                 &ett_smb_lock,
18973                 &ett_smb_open_flags,
18974                 &ett_smb_ipc_state,
18975                 &ett_smb_open_action,
18976                 &ett_smb_setup_action,
18977                 &ett_smb_connect_flags,
18978                 &ett_smb_connect_support_bits,
18979                 &ett_smb_nt_access_mask,
18980                 &ett_smb_nt_create_bits,
18981                 &ett_smb_nt_create_options,
18982                 &ett_smb_nt_share_access,
18983                 &ett_smb_nt_security_flags,
18984                 &ett_smb_nt_trans_setup,
18985                 &ett_smb_nt_trans_data,
18986                 &ett_smb_nt_trans_param,
18987                 &ett_smb_nt_notify_completion_filter,
18988                 &ett_smb_nt_ioctl_flags,
18989                 &ett_smb_security_information_mask,
18990                 &ett_smb_print_queue_entry,
18991                 &ett_smb_transaction_flags,
18992                 &ett_smb_transaction_params,
18993                 &ett_smb_find_first2_flags,
18994 #if 0
18995                 &ett_smb_ioflag,
18996 #endif
18997                 &ett_smb_transaction_data,
18998                 &ett_smb_stream_info,
18999                 &ett_smb_dfs_referrals,
19000                 &ett_smb_dfs_referral,
19001                 &ett_smb_dfs_referral_flags,
19002                 &ett_smb_get_dfs_flags,
19003                 &ett_smb_ff2_data,
19004                 &ett_smb_device_characteristics,
19005                 &ett_smb_fs_attributes,
19006                 &ett_smb_segments,
19007                 &ett_smb_segment,
19008                 &ett_smb_sec_desc,
19009                 &ett_smb_sid,
19010                 &ett_smb_acl,
19011                 &ett_smb_ace,
19012                 &ett_smb_ace_flags,
19013                 &ett_smb_sec_desc_type,
19014                 &ett_smb_quotaflags,
19015                 &ett_smb_secblob,
19016                 &ett_smb_mac_support_flags,
19017                 &ett_nt_access_mask,
19018                 &ett_nt_access_mask_generic,
19019                 &ett_nt_access_mask_standard,
19020                 &ett_nt_access_mask_specific,
19021                 &ett_smb_unicode_password,
19022                 &ett_smb_ea,
19023                 &ett_smb_unix_capabilities
19024         };
19025         module_t *smb_module;
19026
19027         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19028             "SMB", "smb");
19029         proto_register_subtree_array(ett, array_length(ett));
19030         proto_register_field_array(proto_smb, hf, array_length(hf));
19031
19032         register_smb_common(proto_smb);
19033
19034         register_init_routine(&smb_init_protocol);
19035         smb_module = prefs_register_protocol(proto_smb, NULL);
19036         prefs_register_bool_preference(smb_module, "trans_reassembly",
19037                 "Reassemble SMB Transaction payload",
19038                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19039                 &smb_trans_reassembly);
19040         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19041                 "Reassemble DCERPC over SMB",
19042                 "Whether the dissector should reassemble DCERPC over SMB commands",
19043                 &smb_dcerpc_reassembly);
19044         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19045                 "Snoop SID to Name mappings",
19046                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19047                 &sid_name_snooping);
19048
19049         register_init_routine(smb_trans_reassembly_init);
19050         smb_tap = register_tap("smb");
19051 }
19052
19053 void
19054 proto_reg_handoff_smb(void)
19055 {
19056         dissector_handle_t smb_handle;
19057
19058         gssapi_handle = find_dissector("gssapi");
19059         ntlmssp_handle = find_dissector("ntlmssp");
19060
19061         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19062         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19063         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19064         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19065         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19066         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19067         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19068             smb_handle);
19069 }